Reputation: 3988
Say I have the following Java collection:
public static List<Object[]> javaStuff = new ArrayList<Object[]>();
And that, from Scala, I want to refer to that collection, convert it Scala collection and return an Iterator[]
over it.
Can anyone explain to me why the following (toy) code does not compile?
def convertMethod[Array[AnyRef]]() : Iterator[Array[AnyRef]] = {
import scala.collection.JavaConverters._
val r: mutable.Buffer[Array[AnyRef]] = MyTestClass.javaStuff.asScala // This does not compile!
r.iterator
}
More specifically, the error IntelliJ highlights is:
Expression of type Buffer[Array[AnyRef]] does not conform to expected type Buffer[Array[AnyRef]]
...which was quite uninformative. Trying to run the code, the error is a bit more helpful:
Error:(18, 58) type mismatch;
found : scala.collection.mutable.Buffer[scala.Array[Object]]
required: scala.collection.mutable.Buffer[Array[AnyRef]]
val r: mutable.Buffer[Array[AnyRef]] = MyTestClass.javaStuff.asScala
^
At which point, I changed the original code into:
def convertMethod[Array[AnyRef]]() : Iterator[Array[AnyRef]] = {
import scala.collection.JavaConverters._
val r: mutable.Buffer[Array[AnyRef]] = MyTestClass.javaStuff.asScala.map(_.asInstanceOf[Array[AnyRef]])
r.iterator
}
...and it worked!
Now my question really is: why is this necessary? Is there a way to avoid that explicit casting?
Upvotes: 1
Views: 739
Reputation: 32739
The reason is simple. In convertMethod
, Array
is a type parameter and thus does not refer to scala.Array
at all.
You should change this:
def convertMethod[Array[AnyRef]]()
to this:
def convertMethod()
Note that contrary to what shadowlands said in a comment, scala.Array
really is the same thing as a java array (except for the fact that scala arrays are not covariant, but it does not come into play here).
Upvotes: 4
Reputation: 53358
Change
def convertMethod[Array[AnyRef]]() =
to
def convertMethod() =
The first one creates a method that takes a type parameter with name Array
, which by itself takes a type parameter of name AnyRef
(i.e. a higher kinded type). These newly introduced names hide the built in types Array
and AnyRef
.
Upvotes: 3