2017-06-28 3 views
3

Ich Stream lerne und während einer solchen Training ich versuchte, 2-Streams von einem anderen Typ String und Integer über folgenden Code zu verbinden:Concat Strom von String und Integer

Stream<String> fruitStream = Stream.of("Apple", "Mango", "Muskmalon", "Guvava"); 
Stream<Integer> vegetablesStream = Stream.of(1, 2, 3, 4); 

Stream<String> mixStream = Stream.concat(fruitStream, vegetablesStream.map(i -> i.toString())); 
mixStream.forEach(System.out :: println); 

es richtig funktionierte und gab mir gewünscht Ergebnis.

Dann habe ich versucht, Methode Referenz verwenden:

Stream<String> mixStream = Stream.concat(fruitStream, vegetablesStream.map(Integer :: toString)); 

Und es begann Fehler zu werfen:

Wrong 1st argument type. Found: 'java.util.stream.Stream<java.lang.String>', required: 'java.util.stream.Stream<? extends T>' 
concat (java.util.stream.Stream<? extends T>, java.util.stream.Stream<? extends T>) in Stream cannot be applied to (java.util.stream.Stream<java.lang.String>, java.util.stream.Stream<R>)   
reason: No compile-time declaration for the method reference is found 

Wenn ich mit String :: ValueOf meine Methode Referenz ersetzt, es funktioniert gut:

Stream<String> mixStream = Stream.concat(fruitStream, vegetablesStream.map(String :: valueOf)); 

I am unable to understand why Integer :: toString failed but String :: valueOf passed?

+0

Ich wusste, dass dies ein Duplikat sein musste ... – Eugene

Antwort

3

Die Fehlermeldung sollte Ambiguous method reference: both toString() and toString(int) from the type Integer are eligible lauten. Das passiert, weil sowohl toString als auch toString(int) hier verwendet werden können.

Es könnte beide waren:

.map(i -> i.toString(i)) 
    .map(i -> i.toString())  

Und es funktioniert gut, weil String::valueOf keine solche überladene Methode hat und damit der Compiler mit, dass in Ordnung.

+0

Danke Eugene für die Klärung .. Meine Entschuldigung für die doppelte Frage, aber ich war nicht in der Lage, genau das gleiche Szenario zu finden .. Vielleicht muss ich umm um Suchfähigkeiten :) –

+1

Object :: toString wird auch funktionieren. Ich stieß auf dieses Problem, als IntelliJ ein Lambda "i -> i.toString()" mit "Kann durch eine Methodenreferenz ersetzt werden" gekennzeichnet wurde. Ich nehme an, dass diese Nachricht als Ergebnis einer einfachen Syntaxprüfung generiert wird, ohne mögliche Mehrdeutigkeiten zu berücksichtigen? –

+0

@GregH wenn man bedenkt, wie * viele * Dinge in diesen Methodenreferenz-Ersetzer passen könnten, denke ich, dass nur der Syntax-Check das vernünftige Ding zu berichten ist; Schließlich denkt IntelliJ nicht daran zu lesen – Eugene