Search code examples
javascalaarraylistpartial-applicationtoarray

Missing arguments for method toArray in trait List when converting from java ArrayList to scala Array


I have this simple code:

import java.util
import scala.collection.JavaConversions._

def f(x: util.List[Int]): Array[Int] = {
  x.toArray[Int]
}

It is failing on error: missing arguments for method toArray in trait List

However the source code for toArray is the following:

trait TraversableOnce[+A] extends Any with GenTraversableOnce[A] {
...
  def toArray[B >: A : ClassTag]: Array[B] = {
    if (isTraversableAgain) {
      val result = new Array[B](size)
      copyToArray(result, 0)
      result
    }
    else toBuffer.toArray
  }

So clearly there is no missing argument.

1) How is that possible? Is there a simple workaround? Or am I missing something?

2) The error message continue with follow this method with '_' if you want to treat it as a partially applied function. Don't you think it is a stupid proposition? I have declared the return value, so partially applied function cannot work. The compiler should see it.


Solution

  • This looks like it's caused by the fact that java.util.List already defines it's own toArray methods. It defines toArray():Object and toArray(T[]):T[]. Because these are available, it doesn't make the implicit conversion to a Scala List. But the toArray() method on the Java List doesn't have the expected return type, so it needs to use the one that takes a single argument instead (with a generic return type), which is why you get this error message.

    If you do an explicit conversion to a Scala List, then it should find the desired toArray method, and work as expected. So the code should look like this:

    import java.util
    import scala.collection.JavaConverters._
    
    def f(x: util.List[Int]): Array[Int] = {
      x.asScala.toArray[Int]
    }