Created
September 3, 2018 07:43
-
-
Save berdario/9914f690815fd677aee2535be4014cf3 to your computer and use it in GitHub Desktop.
Java type errors can be nasty
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
> javac -Xlint:unchecked Transpose.java | |
Transpose.java:8: error: incompatible types: inference variable R has incompatible bounds | |
return map.entrySet().stream().collect(toMap(e -> e.getValue(), e -> new HashSet<>(Set.of(e.getKey())), (x, y) -> {x.addAll(y); return x;})); | |
^ | |
equality constraints: Map<K,U> | |
upper bounds: HashMap<B,HashSet<A#2>>,Object | |
where R,A#1,T#1,K,T#2,U,B,A#2 are type-variables: | |
R extends Object declared in method <R,A#1>collect(Collector<? super T#1,A#1,R>) | |
A#1 extends Object declared in method <R,A#1>collect(Collector<? super T#1,A#1,R>) | |
T#1 extends Object declared in interface Stream | |
K extends Object declared in method <T#2,K,U>toMap(Function<? super T#2,? extends K>,Function<? super T#2,? extends U>,BinaryOperator<U>) | |
T#2 extends Object declared in method <T#2,K,U>toMap(Function<? super T#2,? extends K>,Function<? super T#2,? extends U>,BinaryOperator<U>) | |
U extends Object declared in method <T#2,K,U>toMap(Function<? super T#2,? extends K>,Function<? super T#2,? extends U>,BinaryOperator<U>) | |
B extends Object declared in method <A#2,B>transposeMap(HashMap<A#2,B>) | |
A#2 extends Object declared in method <A#2,B>transposeMap(HashMap<A#2,B>) | |
1 error | |
# This is probably an instance of this bug: https://bugs.openjdk.java.net/browse/JDK-8196762 the proper solution (adding a type witness) is described there and here: https://stackoverflow.com/questions/38089827/collector-doesnt-match-wildcard-in-result-type | |
# though the wildcard in `toMap` makes it quite puzzling to understand what to fill in. Casting the result of the computation is unfortunately much easier :/ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.HashMap; | |
import java.util.HashSet; | |
import java.util.Set; | |
import static java.util.stream.Collectors.toMap; | |
class Transpose{ | |
static <A, B> HashMap<B, HashSet<A>> transposeMap(HashMap<A, B> map){ | |
return map.entrySet().stream().collect(toMap(e -> e.getValue(), e -> new HashSet<>(Set.of(e.getKey())), (x, y) -> {x.addAll(y); return x;})); | |
} | |
} |
👍
As you noticed, a concrete Set implementation is still needed since as you noticed addAll is an optional operation
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Questo compila:
Output:
Il problema è che
toMap
è unCollector<T, ?, Map<K,U>>
e non unCollector<T, ?, HashMap<K,U>>
. Stavi assumendo uno specifico tipo di mappa, cosa chetoMap
non garantisce in nessun modo. Detto questo, il messaggio di errore è terribile.Inoltre io mi limiterei a dipendere dalle interfacce
Map
eSet
anziché da specifiche implementazioni. La signature ditrasposeMap
dovrebbe essere: