2017-10-19 4 views
2

Kann jemand erklären, warum der folgende Code nicht kompiliert wird, aber der zweite tut?Java Stream Collectors.toList() wird nicht kompilieren

nicht

private void doNotCompile() { 

    List<Integer> out; 
    out = IntStream 
      .range(1, 10) 
      .filter(e -> e % 2 == 0) 
      .map(e -> Integer.valueOf(2 * e)) 
      .collect(Collectors.toList()); 

    System.out.println(out); 
} 

Compilation Fehler auf dem IntStream sammeln Linie

  • Verfahren sammeln (Lieferant, ObjIntConsumer, BiConsumer) in der Art kompilieren Sie ist für die Argumente nicht anwendbar (Collector>)
  • Typ stimmt nicht überein: Konvertierung von Collector> zu Lieferant
  • nicht möglich

Compiliert

private void compiles() { 
    List<Integer> in; 

    in = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9); 
    List<Integer> out; 
    out = in.stream() 
      .filter(e -> e % 2 == 0) 
      .map(e -> 2 * e) 
      .collect(Collectors.toList()); 

    System.out.println(out); 
} 
+4

Beim nächsten Mal fügen Sie die Fehlermeldung hinzu, anstatt nur anzugeben, dass sie nicht kompiliert wird. – AxelH

Antwort

7

IntStream keine collect Methode hat, die eine Collector akzeptiert. Wenn Sie eine List<Integer> wollen, müssen Sie Feld die IntStream in ein Stream<Integer>:

out = IntStream 
     .range(1, 10) 
     .filter(e -> e % 2 == 0) 
     .map(e -> 2 * e) 
     .boxed() 
     .collect(Collectors.toList()); 

Eine Alternative zu .map().boxed() ist mapToObj():

out = IntStream 
     .range(1, 10) 
     .filter(e -> e % 2 == 0) 
     .mapToObj(e -> 2 * e) 
     .collect(Collectors.toList()); 

oder können Sie die IntStreamcollect Methode verwenden:

out = IntStream 
     .range(1, 10) 
     .filter(e -> e % 2 == 0) 
     .map(e -> 2 * e) 
     .collect(ArrayList<Integer>::new, ArrayList::add, ArrayList::addAll); 
+0

"IntStream hat keine Collect-Methode, die einen Collector akzeptiert" ... speziell weil es keine "Liste ' – Michael

+1

@Michael Good Punkt gibt, sollte es einfach "e -> 2 * e" sein. – Eran

1

Die collect Methode von IntStream ist im nicht kompilierbaren Fall anders.

public <R> R collect(Supplier<R> supplier, ObjIntConsumer<R> accumulator, BiConsumer<R,R> combiner) 

Daher ist es nicht die Parameter akzeptieren Sie collect geliefert

Sie um diesen durch Gießen List<Integer> zum IntStream

1

Im ersten Beispiel erhalten könnten, Sie werden über einen Strom von primitivem Betrieb ganze Zahlen. Primitive Ganzzahlen können nicht in eine List, basically because generics in Java are less than ideal gehen. Java-Sprachentwickler sind working on potentially fixing this.

In der Zwischenzeit, um dies zu lösen, müssen Sie diese primitiven Eingänge in eine Integer wrapper zuerst boxen. Ein Codebeispiel finden Sie unter Eran's answer.

Im zweiten Beispiel iterieren Sie bereits über Integer s so Es funktioniert einfach ™.


Ich dachte, ich war Boxen diejenigen ganzen Zahlen int, wenn ich Integer.valueOf in der Mapper hat

Die map function of IntStream eine IntUnaryOperator nimmt die eine funktionale Schnittstelle ist, die eine primitive int nimmt und Gibt ein primitives int zurück.

Die Integer, die Sie von valueOf erhalten, ist ungepfropft, um der funktionalen Schnittstelle zu entsprechen.

+0

Danke, aber ich dachte, ich boxte diese int zu Ganzzahlen, wenn ich Integer.valueOf im Mapper – Vasco

+0

meine Antwort :) – Michael

+0

Ich bekomme es jetzt, es funktioniert auch, wenn ich maptoObj statt Karte verwenden – Vasco

Verwandte Themen