0

The following code gives me compilation error:

//C1 c1 = ....;
//C2 c2 = ....;
List<Pair<Pair<C1, String>, C2>>> l = someMethod().stream()
         .map(item -> ImmutablePair.of(ImmutablePair.of(c1, "hello"), c2))
         .collect(Collectors.toList());

But when I change it to the following, it works fine:

//C1 c1 = ....;
//C2 c2 = ....;
List<Pair<Pair<C1, String>, C2>>> l = someMethod().stream()
         .map(item -> {
               Pair<Pair<C1, String>, C2> r = ImmutablePair.of(ImmutablePair.of(c1, "hello"), c2);
               return r;
         })
         .collect(Collectors.toList());

I thought maybe it's because of casting (which I don't get why it should need to be casted) and I change the code to the following, but I still see the "Incompatible type" error:

//C1 c1 = ....;
//C2 c2 = ....;
List<Pair<Pair<C1, String>, C2>>> l = someMethod().stream()
         .map(item -> 
               (Pair<Pair<C1, String>, C2>)ImmutablePair.of(ImmutablePair.of(c1, "hello"), c2)
         })
         .collect(Collectors.toList());

How can I write this in one line to work? and why doesn't it figure out itself? What's the ambiguity?

Arian
  • 7,397
  • 21
  • 89
  • 177
  • What is return type of `someMethod()`, what is `c1` and `c2`, and why aren't you using `item`? – Andreas Sep 16 '19 at 02:33
  • Possible duplicate of [Is List a subclass of List? Why are Java generics not implicitly polymorphic?](https://stackoverflow.com/questions/2745265/is-listdog-a-subclass-of-listanimal-why-are-java-generics-not-implicitly-po) – smac89 Sep 16 '19 at 02:34
  • This has to do with Java's generic system. `List` is not a supertype of `List`. The same goes for your case: `List>` is not a supertype of `List>` – smac89 Sep 16 '19 at 02:35
  • then why second case succeeds, and not the third one? – Arian Sep 16 '19 at 02:37
  • In the second case, the same thing is happening: `Pair>` is not a super type of `ImmutablePair>`. Try casting it to `Pair extends Pair, C2>` – smac89 Sep 16 '19 at 02:39
  • but the second case doesn't give compilation error. – Arian Sep 16 '19 at 02:44
  • Good point. I am not sure then why that works and the other one doesn't – smac89 Sep 16 '19 at 02:55
  • Just as a sidenote, if you return `return ImmutablePair.of((Pair)ImmutablePair.of(c1, "hi"), c2);`, it works. I'm still convinced this problem has to do with the lack of contravariant inheritance in Java, but I don't have full knowledge of every aspect of it, especially with assignment and inheritance – smac89 Sep 16 '19 at 03:06

1 Answers1

0

The compiler can't infer the types of your Pair. This happens when one of your types is generic as well. In this case, explicitly telling the compiler what your types are should work.

List<Pair<Pair<C1, String>, C2>>> l = someMethod().stream()
         .map(item -> ImmutablePair.<Pair<C1, String>, C2>>of(ImmutablePair.of(c1, "hello"), c2))
         .collect(Collectors.toList());
Yan Fayman
  • 21
  • 4