12 gängige Möglichkeiten zur Verwendung von Java Streams
Quelle: Dev.to Die Java Streams API erschien erstmals in Java 8. Ihr Zweck besteht darin, eine kompaktere Möglichkeit zur Durchführung allgemeiner Operationen an Objektsammlungen bereitzustellen. Außerdem kann die Java Streams API zur Implementierung komplexer Algorithmen verwendet werden. In diesem Artikel werden wir über häufige Anwendungsfälle von Java Streams sprechen. Lassen Sie uns zunächst einige Grundlagen klären:-
stream() – erstellt einen Stream aus der Sammlung.
-
Collect() – sammelt einen Stream in einem Objekt. Ein Objekt kann eine Sammlung, ein Grundelement oder eine benutzerdefinierte Klasse sein.
-
Collectors ist eine Klasse, die (viele) statische Methoden zum Sammeln von Streams bereitstellt.
1. Filtern
-
Wird verwendet, um Werte basierend auf einer Bedingung aus einer Sammlung zu entfernen.
-
Um Sammlungselemente basierend auf einer Bedingung zu filtern, verwenden Sie die Methode filter() . Es werden nur passende Elemente gespeichert.
List<Integer> evenNumbers = originalList.stream()
.filter(n -> n % 2 == 0)
.collect(Collectors.toList());
2. Vorverarbeitung
-
Nützlich, wenn jeder Wert in einer Sammlung direkt geändert werden muss.
-
Die Methode „map()“ wird verwendet, um eine Funktion auf jedes Element der Sammlung anzuwenden und eine neue Sammlung berechneter Werte zurückzugeben.
List<Integer> squares = originalList.stream()
.map(n -> n * n)
.collect(Collectors.toList());
3. Konvertierung
-
Nützlich, wenn wir eine Sammlung in eine andere Sammlung umwandeln möchten.
-
Es gibt mehrere Möglichkeiten, dies zu erreichen.
Beispiel 1: Erstellen Sie eine Karte aus Listen.
Konvertieren Sie eine Liste von Zeichenfolgen in eine Zuordnung von Zeichenfolgen und Längen.Map<String, Integer> wordLengths = words.stream()
.collect(Collectors.toMap(
word -> word,
word -> word.length()));
Beispiel 2. Konvertieren einer Liste in Mengen.
Dies ist ein häufiger Anwendungsfall zum Entfernen von Duplikaten. Wenn wir Elemente wieder in die Liste einfügen möchten, können wir außerdem die Methoden stream() und Collect() zweimal verwenden . Lassen Sie uns beispielsweise eine Liste von Zeichenfolgen in eine Liste eindeutiger Zeichenfolgen konvertieren:// if we want to collect to a set
Set<String> uniqueWords = words.stream()
.collect(Collectors.toSet());
// OR
// if we want to start and end as a list
List<String> uniqueWords = words.stream()
.collect(Collectors.toSet()).stream().collect(Collectors.toList());
Beispiel 3. Konvertieren einer Produktliste in eine Liste ihrer Namen. (Abflachung – Ausrichtung)
List<String> productNames = products.stream()
.map(product -> product.getName())
.collect(Collectors.toList());
4. Reduzierung
-
Reduziert die Sammlung auf einen einzelnen Wert.
-
Die Methode „reduce()“ wird verwendet, um eine Funktion auf jedes Element der Sammlung anzuwenden und einen einzelnen Wert zurückzugeben.
int sum = numbers.stream()
.reduce(0, (a, b) -> a + b);
5. Gruppierung
-
Gruppiert die Elemente einer Sammlung basierend auf einer bestimmten Bedingung.
-
Um Sammlungselemente nach Bedingung zu gruppieren, verwenden Sie die Methode Collectors.groupingBy() .
Map<String, List<Product>> productsByCategory = products.stream()
.collect(Collectors.groupingBy(product -> product.getCategory()));
6. Finden
-
Sucht nach dem ersten oder einem beliebigen Collection-Element, das einer Bedingung entspricht.
-
Für die Suche werden die Methoden findFirst() und findAny() verwendet .
Optional<String> firstLongWord = words.stream()
.filter(word -> word.length() > 5)
.findFirst();
// Note that findFirst() and findAny() methods return Optional<T> objects.
7. Sortieren
-
Sortiert die Elemente von Sammlungen.
-
Zum Sortieren wird die Methode sorted() verwendet .
List<Integer> topK = numbers.stream()
.sorted()
.limit(k)
.collect(Collectors.toList());
8. Partitionierung
-
Trennt die Elemente einer Sammlung basierend auf einer bestimmten Bedingung.
-
Die Methode Collectors.partitioningBy() wird zum Trennen von Elementen verwendet .
Map<Boolean, List<Student>> passingFailing = students
.stream()
.collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD));
9. Zählen
-
Zählt die Anzahl der Elemente, die einer Bedingung entsprechen.
-
Mit der Methode count() wird die Anzahl der Elemente gezählt, die einer Bedingung entsprechen .
long count = words.stream()
.filter(word -> word.length() > 5)
.count();
10. Reichweite
-
Erstellt einen Wertebereich.
-
Um einen Wertebereich zu erstellen, verwenden Sie die Methode range() .
int[] numbers = IntStream.range(0, 10).toArray();
11. Passend
-
Ordnet die Elemente einer Sammlung einem Prädikat (Bedingung) zu.
-
Methoden wie anyMatch() , allMatch() und noneMatch() werden verwendet, um Sammlungselemente mit einem Prädikat abzugleichen und einen booleschen Wert zurückzugeben .
// true when all elements match the predicate
boolean allMatch = products.stream()
.allMatch(product -> product.getPrice() > 10);
// true when any element matches the predicate
boolean anyMatch = products.stream()
.anyMatch(product -> product.getPrice() > 10);
// true when no elements match the predicate
boolean noneMatch = products.stream()
.noneMatch(product -> product.getPrice() > 10);
12. Beitritt
-
Verkettet die Elemente einer Sammlung zu einer Zeichenfolge.
-
Um Sammlungselemente zu einer Zeichenfolge zusammenzufügen, verwenden Sie die Methode Collectors.joining() .
String joinedWords = words.stream()
.collect(Collectors.joining(" "));
Das war's für allgemeine Szenarien. Es gibt andere, weniger häufige Szenarien, die Sie selbst erkunden können:
- Parallele Streams;
- Statistiken;
- Benutzerdefinierte Sammler.
Vorteile von Threads
-
Kompakterer Code – reduziert die Menge an Code, die zum Verarbeiten der Sammlung erforderlich ist.
-
Weniger Zwischenvariablen. Durch eingreifende Variablen kann es zu Fehlern kommen. Je weniger es sind, desto einfacher lassen sich unerwartete Fehler vermeiden.
-
Intuitiver Code. Einige Entwickler sind anderer Meinung, dass Threads intuitiver sind als andere Methoden. Sobald wir uns jedoch daran gewöhnt haben, werden sie viel intuitiver als andere Methoden.
So bewerten Sie die Speicherzuordnung eines Objekts in Java
Quelle: DZone Dieser Artikel zeigt die drei bekanntesten Methoden zur Bewertung der Speicherzuordnung eines Objekts in Java.Gedächtnisbewertung mit Profiler
Der einfachste Weg, den Speicher einiger Objekte abzuschätzen, besteht darin, mit einem Profiler wie Visual VM direkt in den JVM-Speicher zu schauen . Das Problem bei diesem Ansatz besteht darin, dass Sie eine Verbindung zu einer laufenden JVM herstellen müssen, was aus Sicherheitsgründen in Produktionsumgebungen möglicherweise nicht möglich ist.Gedächtnisbewertung mit Instrumenten
Eine andere Möglichkeit, den zugewiesenen Speicher für ein bestimmtes Objekt abzuschätzen, ist die Verwendung von Instrumenten. Vereinfacht ausgedrückt müssen wir eine Klasse erstellen und diese in ein JAR kompilieren. Nachdem wir die JAR erstellt haben, müssen wir unsere JVM zusammen mit dieser JAR ausführen. Mehr über diese Methode erfahren Sie hier . Der Nachteil besteht darin, dass der JVM eine bestimmte JAR-Datei hinzugefügt werden muss, die aus Sicherheits- oder ähnlichen Gründen möglicherweise nicht für die Produktion geeignet ist.Gedächtnisbewertung mit der JOL-Bibliothek
Als weitere Option können wir die JOL-Bibliothek verwenden . Dies ist eine sehr leistungsstarke Bibliothek, die eine detaillierte Schätzung des Gewichts eines Objekts und des von einer Objektinstanz zugewiesenen Speichers liefern kann. Um die Bibliothek nutzen zu können, müssen wir eine Abhängigkeit hinzufügen:<dependency>
<groupId>org.openjdk.jol</groupId>
<artifactId>jol-core</artifactId>
<version>0.16</version>
</dependency>
Danach können wir es wie folgt verwenden:
out.println(GraphLayout.parseInstance(myObject).totalSize() / 1024000d + " MB")
ObjectSizeCalculator aus dem Twitter-Archiv
Das öffentliche GitHub- Repository von Twitter verfügt über eine Toolklasse namens ObjectSizeCalculator , die den zugewiesenen Speicher für eine bestimmte Objektinstanz schätzen kann. Die Verwendung erfordert nicht viel Speicher oder Zeit. Der Auswertungsprozess dauert selbst bei großen Objekten Sekunden. Die Verwendung dieser Klasse ist ganz einfach:ObjectSizeCalculator.getObjectSize(address)
Ich empfehle diese Methode, bedenken Sie jedoch, dass sie nur von Java Hotspot, OpenJDK und TwitterJDK unterstützt wird.
GO TO FULL VERSION