2

When being in scala and I write

val data: java.util.List[java.util.List[Double]] = new java.util.ArrayList[java.util.ArrayList[Double]]()

I get the error

Expression of type util.ArrayList[util.ArrayList[Double]] does not conform to expected type util.List[util.List[Double]]

What am I doing wrong?

Make42
  • 12,236
  • 24
  • 79
  • 155
  • 2
    I guess it's something like this `val data: java.util.List[java.util.List[Double]] = new java.util.ArrayList[java.util.List[Double]]()` – Joachim Huet Nov 15 '17 at 15:06
  • @JoachimHuet: Thanks! That worked. If you like you can turn that into an answer - maybe providing an explanation (otherwise people will comment, it has too little content). I will except it then. – Make42 Nov 15 '17 at 15:09

2 Answers2

2

You should rather use val data: java.util.List[java.util.List[Double]] = new java.util.ArrayList[java.util.List[Double]]()

Because generic types are not polymorphic in Java. See this

You could also have write the following in order to explicit the type :

val data: java.util.List[? extends java.util.List[Double]] = new java.util.ArrayList[java.util.ArrayList[Double]]()

To be easily understood List<A> is not a super of List<B> even if B extends A.

Joachim Huet
  • 422
  • 3
  • 10
  • 1. Java generic types aren't polymorphic, Scala types can be. 2. The Scala syntax for the last type is `java.util.List[_ <: java.util.List[Double]]`. – Alexey Romanov Nov 15 '17 at 18:32
  • @AlexeyRomanov: With 2. I get errors later on, when passing `data` to methods that except `java.util.List[java.util.List[Double]]`: the method signature does not exist. – Make42 Nov 16 '17 at 09:10
  • @Make42 To work with those methods, you need the first solution, they aren't equivalent. `java.util.List[_ <: java.util.List[Double]]` is a supertype of `java.util.List[java.util.List[Double]]`, so it's like passing `Object` to methods expecting `String`: you want to get errors! – Alexey Romanov Nov 16 '17 at 09:19
  • @AlexeyRomanov: Sorry, for my slow understanding: What do you mean with "first solution"? Maybe you can write an answer and explain in smaller steps? I think this would also be helpful for readers in the future :-). – Make42 Nov 16 '17 at 11:11
  • @Make42 The one in the first sentence: `val data: java.util.List[java.util.List[Double]] = new java.util.ArrayList[java.util.List[Double]]()`. – Alexey Romanov Nov 16 '17 at 11:43
1

My answer applies to Java but I guess that the reason is the same.

You are mixing polymorphism by subtype with generics. It's true that an ArrayList<T> can be assigned to a List<T> variable but here you have a List<List<T>> and you are trying to assign an object of type ArrayList<ArrayList<T>>.

But a List<E> is not a subtype of List<F> even if F is a subtype of E so this is not allowed directly (invariance), but Scala has tools to manage this issue (as Java has bounds and wildcards).

Jack
  • 131,802
  • 30
  • 241
  • 343