it-swarm.com.de

Warum sollte ich "Funktionsoperationen" anstelle einer for-Schleife verwenden?

for (Canvas canvas : list) {
}

NetBeans schlägt mir vor, "funktionale Operationen" zu verwenden:

list.stream().forEach((canvas) -> {
});

Aber warum ist das bevorzugt? Wenn überhaupt, ist es schwieriger zu lesen und zu verstehen. Sie rufen stream() und dann forEach() mit einem Lambda-Ausdruck mit dem Parameter canvas auf. Ich sehe nicht, wie das schöner ist als die for - Schleife im ersten Snippet.

Offensichtlich spreche ich nur aus ästhetischer Sicht. Vielleicht gibt es hier einen technischen Vorteil, den ich vermisse. Was ist es? Warum sollte ich stattdessen die zweite Methode verwenden?

42
Omega

Streams bieten eine viel bessere Abstraktion für die Komposition verschiedener Vorgänge, die Sie zusätzlich zu eingehenden Sammlungen oder Datenströmen ausführen möchten. Insbesondere, wenn Sie Elemente zuordnen, filtern und konvertieren müssen.

Ihr Beispiel ist nicht sehr praktisch. Betrachten Sie den folgenden Code von der Oracle-Site .

List<Transaction> groceryTransactions = new Arraylist<>();
for(Transaction t: transactions){
  if(t.getType() == Transaction.GROCERY){
    groceryTransactions.add(t);
  }
}
Collections.sort(groceryTransactions, new Comparator(){
  public int compare(Transaction t1, Transaction t2){
    return t2.getValue().compareTo(t1.getValue());
  }
});
List<Integer> transactionIds = new ArrayList<>();
for(Transaction t: groceryTransactions){
  transactionsIds.add(t.getId());
}

kann mit Streams geschrieben werden:

List<Integer> transactionsIds = 
    transactions.stream()
                .filter(t -> t.getType() == Transaction.GROCERY)
                .sorted(comparing(Transaction::getValue).reversed())
                .map(Transaction::getId)
                .collect(toList());

Die zweite Option ist viel besser lesbar. Wenn Sie also verschachtelte Schleifen oder verschiedene Schleifen haben, die eine Teilverarbeitung durchführen, ist dies ein sehr guter Kandidat für die Verwendung der Streams/Lambda-API.

46
luboskrnac

Ein weiterer Vorteil der Verwendung der funktionalen Streaming-API besteht darin, dass Implementierungsdetails ausgeblendet werden. Es beschreibt nur, was zu tun ist, nicht wie. Dieser Vorteil wird deutlich, wenn man sich die Änderung ansieht, die vorgenommen werden muss, um von der Ausführung mit einem Thread zur parallelen Codeausführung zu wechseln. Ändern Sie einfach die .stream() in .parallelStream().

16
Stefan Dollase

Wenn überhaupt, ist es schwieriger zu lesen und zu verstehen.

Das ist sehr subjektiv. Ich finde die zweite Version viel einfacher zu lesen und zu verstehen. Es entspricht der Vorgehensweise anderer Sprachen (z. B. Ruby, Smalltalk, Clojure, Io, Ioke, Seph) und erfordert weniger Konzepte zum Verständnis (es ist nur ein normaler Methodenaufruf wie jedes andere, während das erste Beispiel eine spezialisierte Syntax ist).

Wenn überhaupt, ist es eine Frage der Vertrautheit.

13
Jörg W Mittag