1

Can anyone explain why the following error occurs (Scala 2.10.3)?

scala> new java.util.ArrayList[Integer]()
res0: java.util.ArrayList[Integer] = []

scala> res0.add(0)
res1: Boolean = true

scala> java.util.Collections.binarySearch(res0, 0)
<console>:9: error: type mismatch;
 found   : java.util.ArrayList[Integer]
 required: java.util.List[_ <: Comparable[_ >: Any]]
              java.util.Collections.binarySearch(res0, 0)
                                                 ^

The following does work:

scala> java.util.Collections.binarySearch[Integer](res0, 0)
res4: Int = 0

It seems odd that the compiler would complain about a particular type until I was more explicit about that incorrect type and then it will accept it.

EDIT:

Also note the if you change the first step to:

scala> new java.util.ArrayList[Int]()

there is also a very similar error.

2 Answers 2

8

Try this:

java.util.Collections.binarySearch(res0, 0: Integer)

As you can see, it compiles fine. The problem was that 0 has type Int, not Integer. So you have to tell scala somehow that you want to convert 0 into a Integer value.

As it stands, your code triggers the compiler to look for a method binarySearch which takes and ArrayList[Integer] as its first parameter, and an Int as its second parameter.

Sign up to request clarification or add additional context in comments.

4 Comments

Makes sense, but I'm still not sure I understand the logic of the message. Is it that Integer doesn't conform to _ <: Comparable[_ >: Any], but Int does?
Well the compiler does not know if the error comes from the type of the first parameter, or from the type of the second (or both). All it can tell is that this combination of types is invalid (there is no method binarySearch which can take an ArrayList[Integer] as its first aprameter and an Int as its second one. Granted, it may be nicer if the compiler just said it cannot make the call given the input types, rather than emiting a message that can lead you to think that only the first parameter is faulty.
But if I do the exact same steps, just changing the initial List creation to new java.util.ArrayList[Int](), I get the same error! Shouldn't that work by your explanation? Thanks.
java.util.ArrayList[Int] does not conform to java.util.List[_ <: java.lang.Comparable[_ >: Any]] simply because Int is not a sub-type of java.lang.Comparable (but java.lang.Integer is). So the compiler is entrely right to complain if you pass an instance of java.util.ArrayList[Int] to binarySearch
0

Definition of binarySearch is as follows:

Searches the specified list for the specified object using the binary search algorithm.

static <T> int
binarySearch(List<? extends Comparable<? super T>> list, T key)

As you can see, list and key are parameterized on a type T. Now Scala compiler tries to infer the type of list in following invocation:

scala> java.util.Collections.binarySearch(l, 0)
<console>:9: error: type mismatch;
 found   : java.util.ArrayList[Integer]
 required: java.util.List[_ <: Comparable[_ >: Any]]
              java.util.Collections.binarySearch(l, 0)

And the common type between the parameters list and key is Any. Because former is of type List<Integer> and later is of type int as per Java. So this converts in Scala to Integer and int respectively, as explained below:

scala> classOf[Integer]
res9: Class[Integer] = class java.lang.Integer

scala> classOf[Int]
res10: Class[Int] = int

1 Comment

@david: Yes, it makes much sense now :-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.