java8 Sammler.toMap() Einschränkung?
Ich versuche, mit java8 ist Collectors.toMap
auf eine Stream
von ZipEntry
. Es ist vielleicht nicht die beste Idee, weil der möglichen Ausnahmen auftreten, während der Verarbeitung, aber ich denke, es sollte möglich sein.
Ich bin jetzt immer einen compile-Fehler (Typ-Inferenz-engine, die ich denke) was ich nicht verstehe.
Hier einige extrahierte demo-code:
import java.io.IOException;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
public class TestMapCollector {
private static class MyObject {
}
public static void main(String[] argv) throws IOException {
try (ZipFile zipFile = new ZipFile("test")) {
Map<String, MyObject> result = zipFile.stream()
.map(ZipEntry::getName)
.collect(Collectors.toMap(f -> "test", f -> new MyObject()));
}
}
}
Dieser code baut als-ist, aber es nicht bauen, wenn Sie nur Kommentar der .map(ZipEntry::getName)
Linie. Als wenn die toMap
Sammler könnte funktionieren, wenn der Eingang ist ein stream von String
aber nicht, wenn der Eingang ist ein stream von ZipEntry
?
Referenz, hier ist der Beginn der build-Fehler, es ist ziemlich verworren:
no suitable method found for collect(Collector<Object,CAP#1,Map<String,MyObject>>)
method Stream.<R#1>collect(Supplier<R#1>,BiConsumer<R#1,? super CAP#2>,BiConsumer<R#1,R#1>) is not applicable
(cannot infer type-variable(s) R#1
(actual and formal argument lists differ in length))
method Stream.<R#2,A>collect(Collector<? super CAP#2,A,R#2>) is not applicable
(cannot infer type-variable(s) R#2,A,CAP#3,T#2,K,U
(argument mismatch; Collector<CAP#2,CAP#4,Map<Object,Object>> cannot be converted to Collector<? super CAP#2,CAP#4,Map<Object,Object>>))
where R#1,T#1,R#2,A,T#2,K,U are type-variables:
R#1 extends Object declared in method <R#1>collect(Supplier<R#1>,BiConsumer<R#1,? super T#1>,BiConsumer<R#1,R#1>)
T#1 extends Object declared in interface Stream
R#2 extends Object declared in method <R#2,A>collect(Collector<? super T#1,A,R#2>)
A extends Object declared in method <R#2,A>collect(Collector<? super T#1,A,R#2>)
T#2 extends Object declared in method <T#2,K,U>toMap(Function<? super T#2,? extends K>,Function<? super T#2,? extends U>)
K extends Object declared in method <T#2,K,U>toMap(Function<? super T#2,? extends K>,Function<? super T#2,? extends U>)
U extends Object declared in method <T#2,K,U>toMap(Function<? super T#2,? extends K>,Function<? super T#2,? extends U...
- Welchen compiler hast du benutzt? Getestet habe ich
jdk1.8.0_05
,jdk1.8.0_20
,jdk1.8.0_40beta
, undEclipse Luna (4.4.0)
; keiner von Ihnen hatte keine Probleme beim kompilieren des Codes. - Ich kann das Problem reproduzieren (die Sie benötigen, um zu kommentieren
.map(ZipEntry::name)
out) mit jdk1.8.0_20 mit javac. - Ich sehe. Seit dem 1.8u20 ist die einzige in meiner Liste haben das problem, wir haben ein Duplikat von diese Frage (oder vielleicht auch bezogen auf diese Frage)?
- ja, ich war mit u20 (spätestens ab jetzt). so scheint es, könnte es behoben werden in künftigen Versionen, gut zu hören.
- Ich habe gesehen, dass dies in u31 und kann bestätigen, es ist verschwunden im u60
- Ich habe auch einen ähnlichen Fehler in einem anderen Kontext mit
jdk1.8.0_25
und nicht mitjdk1.8.0_65
.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Das problem scheint zu sein aufgrund der Tatsache, dass der stream-Typ verwendet wild cards - nicht sicher, ob dies ist das erwartete Verhalten. Ein workaround wäre:
((Stream<ZipEntry>)zipFile.stream())
anstatt einfach aufrufenstream()
es kompiliert. So, eine Beschränkung der java8-Typ-Inferenz, wie es scheint.