in Java I have been using gson to parse a json like this [[1.2, 4.1], [3.4, 4.4]] into a java primitive multi-array double[][]
The code looks like this (and works fine) :
String json = "[[1.2, 4.1], [3.4, 4.4]]"
double[][] variable = new Gson().fromJson(json, double[][].class);
Is there a way to get the double[][].class in kotlin ?
Is double[][] variable; can be substitute in kotlin ?
Edit :
My goal is to achieve the same behavior with gson in kotlin. I have thousand of doubles arrays to parse.
I would like to do something like this in kotlin :
val json = "[[1.1, 1.2], [2.1, 2.2, 2.3], [3.1, 3.2]"
val variable:Double[][] = Gson().fromJson(json, Double[][]::class.java)
Answer to the Gson problem
For the class type of your use case use Array<DoubleArray>::class.java)
Some additional Words on Multidimensional Arrays
Simply wrap arrayOf into another arrayOf or doubleArrayOf (less Boxing overhead) to get something like Array<DoubleArray>:
val doubles : Array<DoubleArray> = arrayOf(doubleArrayOf(1.2), doubleArrayOf(2.3))
It's also possible to nest multiple Array initializers with the following constructor:
public inline constructor(size: Int, init: (Int) -> T)
A call can look like this:
val doubles2: Array<DoubleArray> = Array(2) { i ->
DoubleArray(2) { j ->
j + 1 * (i + 1).toDouble()
}
}
//[[1.0, 2.0], [2.0, 3.0]]
In the future, you can try using the Kotlin converter. I took your code and ran it through the converter and got the following working code which agrees with the answer given.
internal var json = "[[1.2, 4.1], [3.4, 4.4]]"
internal var variable = Gson().fromJson(json, Array<DoubleArray>::class.java)
You can mix arrayOf and doubleArrayOf for that case.
arrayOf(
doubleArrayOf(1.2, 4.1)
doubleArrayOf(3.4, 4.4)
)
Related
I'm trying to read in a .yaml file into my Scala code. Assume I have the following yaml file:
animals: ["dog", "cat"]
I am trying to read it using the following code:
val e = yaml.load(os.read("config.yaml")).asInstanceOf[java.util.Map[String, Any]]
val arr = e.getOrDefault("animals", new Java.util.ArrayList[String]()) // arr is Option[Any], but I know it contains java.util.ArrayList<String>
arr.asInstanceOf[Buffer[String]] // ArrayList cannot be cast to Buffer
The ArrayList is type Any, so how do I cast to a Scala Collection e.g. Buffer? (Or Seq, List...)
SnakeYaml (assuming what you're using) can't give you a scala collection like Buffer directly.
But you can ask it for ArrayList of string and then convert it to whatever you need.
import scala.jdk.CollectionConverters._
val list = arr.asInstanceOf[util.ArrayList[String]].asScala
results in:
list: scala.collection.mutable.Buffer[String] = Buffer(dog, cat)
Another option you have is to define the model of you configuration, for example:
class Sample {
#BeanProperty var animals = new java.util.ArrayList[String]()
}
The following will create an instance of Sample:
val input = new StringReader("animals: [\"dog\", \"cat\"]")
val yaml = new Yaml(new Constructor(classOf[Sample]))
val sample = yaml.load(input).asInstanceOf[Sample]
Then, using CollectionConverters in Scala 2.13, or JavaConverters in Scala 2.12 or prior, convert animals into a Scala structure:
val buffer = sample.getAnimals.asScala
Code run at Scastie.
I am trying to use a uriArray for parsing path of images but stuck at one point in kotlin, it's giving me issue of required Array! found Array
val uriArray = arrayOfNulls<Uri>(imageList.size)
for (i in imageList.indices) {
val imgaesModel = imageList.get(i)
uriArray[i] = Uri.parse("file:" + imgaesModel.getPath())
}
mFilePathCallback!!.onReceiveValue(uriArray)
// Above line is giving error
Please give me some suggestions as I am new to Kotlin, little will be appreciated.
An alternative to tasoluko's answer is
val uriArray = Array<Uri>(imageList.size) { i ->
val imagesModel = imageList[i] // get method can be written as indexing
Uri.parse("file:" + imagesModel.path) // instead of getPath()
}
Since you are using arrayOfNulls, your uriArray consists Uri? (nullable Uri) elements. Because of that onReceiveValue can not receive expected type which is an array of Uri, instead, it receives an array of Uri?. What I suggest is instead of creating an arrayOfNulls, use map function in kotlin to convert imageList into a Uri list, and then convert that list to an array and use it.
It should be something like this I think.
val uriList = imagesList.map {
Uri.parse("file:" + it.getPath())
}
val uriArray = uriList.toTypedArray() // something like this just convert list to array :)
mFilePathCallback!!.onReceiveValue(uriArray)
I am implementing a Kotlin interface in Java which expects me to return a Sequence<T>.
How can I convert a Java collection into a Kotlin Sequence? Conversely, how can I convert a Kotlin Sequence into a Java collection?
Here are some conversions:
val javaList = java.util.ArrayList<String>()
javaList.addAll(listOf("A", "B", "C"))
// From Java List to Sequence
val seq = sequenceOf(*javaList.toTypedArray())
// or
val seq2 = javaList.asSequence()
// Sequence to Kotlin List
val list = seq.toList()
// Kotlin List to Sequence
val seqFromList = sequenceOf(*list.toTypedArray())
// or
val seqFromList2 = list.asSequence()
// Sequence to Java List
val newJavaList = java.util.ArrayList<String>().apply { seqFromList.toCollection(this) }
// or
val newJavaList2 = java.util.ArrayList<String>()
newJavaList2.addAll(seqFromList)
Since the Kotlin code gets run from Java, it gets a bit trickier.
Let's try to recreate the scenario:
Kotlin:
interface SequenceInterface {
fun foo(list: List<Int>) : Sequence<Int>
}
If you inspect Kotlin code, you will discover that there's no particular implementation of the Sequence interface. So, in your case, you need to implement it by yourself (just like Kotlin is doing when calling asSequence:
public class Foo implements SequenceInterface {
#NotNull
public Sequence<Integer> foo(final List<Integer> list) {
return () -> list.listIterator();
}
}
and then you can start using it in Java:
new Foo().foo(Arrays.asList(42))
Keep in mind that all useful methods will be gone since they are implemented as Kotlin extensions.
Want to convert to List? In plain Java, just reiterate:
ArrayList<Integer> list = new ArrayList<>();
seq.iterator().forEachRemaining(list::add);
Also, make sure that you absolutely need to return a Sequence in Kotlin's code. If you want to achieve better interoperability, returning a Stream would make more sense.
Like this:
val javaList = java.util.ArrayList<String>()
val kotlinSeq = javaList.asSequence()
val newJavaList = java.util.ArrayList<String>().apply { kotlinSeq.toCollection(this) }
I'm trying to convert from a java List to a scala List[scala.Long], i have seen from scala to java, but not the other way around.
I have tried using:
def convertJavaList2ScalaList[A]( list : java.util.List[A] ) : List[A]
={
val buffer = list.asScala
buffer.toList
}
And it works for other Objects (Eg. Person), but doesn't work when i try to convert scala.Long to java.lang.Long
Thanks for the help.
import scala.collection.JavaConverters._
// given a Java List of Java Longs:
val jlist: java.util.List[java.lang.Long] = ???
val scalaList: List[Long] = jlist.asScala.toList.map(_.toLong)
I am new to scala and spark.I have below case class A
case class A(uniqueId : String,
attributes: HashMap[String, List[String]])
Now I have a dataFrame of type A. I need to call a java function on each row of that DF. I need to convert Hashmap to Java HashMap and List to java list..
How can i do that.
I am trying to do following
val rddCaseClass = RDD[A]
val a = rddCaseClass.toDF().map ( x=> {
val rowData = x.getAs[java.util.HashMap[String,java.util.List[String]]]("attributes")
callJavaMethod(rowData)
But this is giving me error :
java.lang.ClassCastException: scala.collection.mutable.WrappedArray$ofRef cannot be cast to java.util.List
Please help.
You can convert Scala Wrapped array to Java List using
scala.collection.JavaConversions
val wrappedArray: WrappedArray[String] = WrappedArray.make(Array("Java", "Scala"))
val javaList = JavaConversions.mutableSeqAsJavaList(wrappedArray)
JavaConversions.asJavaList can also be used but its deprecated: use mutableSeqAsJavaList instead
I think, you could use Seq instead of List for your parameters to work efficiently with List. This way it should work with most of the Seq implementations and no need to to convert the seqs like WrappedArray.
val rddCaseClass = RDD[A]
val a = rddCaseClass.toDF().map ( x=> {
val rowData = x.getAs[java.util.HashMap[String, Seq[String]]]("attributes")
callJavaMethod(rowData)