Java 8 - Streams
Stream ist eine neue abstrakte Schicht, die in Java 8 eingeführt wurde. Mit Stream können Sie Daten ähnlich wie bei SQL-Anweisungen deklarativ verarbeiten. Betrachten Sie beispielsweise die folgende SQL-Anweisung.
SELECT max(salary), employee_id, employee_name FROM Employee
Der obige SQL-Ausdruck gibt automatisch die Details des maximal bezahlten Mitarbeiters zurück, ohne Berechnungen auf Seiten des Entwicklers durchzuführen. Bei Verwendung des Sammlungs-Frameworks in Java muss ein Entwickler Schleifen verwenden und wiederholte Prüfungen durchführen. Ein weiteres Anliegen ist die Effizienz; Da Mehrkernprozessoren ohne weiteres verfügbar sind, muss ein Java-Entwickler eine parallele Codeverarbeitung schreiben, die ziemlich fehleranfällig sein kann.
Um solche Probleme zu lösen, wurde mit Java 8 das Stream-Konzept eingeführt, das es dem Entwickler ermöglicht, Daten deklarativ zu verarbeiten und die Multicore-Architektur zu nutzen, ohne dafür speziellen Code schreiben zu müssen.
Was ist Stream?
Stream stellt eine Sequenz von Objekten aus einer Quelle dar, die Aggregatoperationen unterstützt. Im Folgenden sind die Merkmale eines Streams aufgeführt:−
-
Reihenfolge von Elementen − Ein Stream stellt sequentiell eine Reihe von Elementen eines bestimmten Typs bereit. Ein Stream erhält/berechnet Elemente nach Bedarf. Es speichert niemals die Elemente.
-
Quelle − Stream nimmt Collections, Arrays oder I/O-Ressourcen als Eingabequelle.
-
Aggregierte Vorgänge − Stream unterstützt aggregierte Operationen wie Filtern, Zuordnen, Begrenzen, Reduzieren, Finden, Abgleichen usw.
-
Rohrleitung − Die meisten Stream-Operationen geben den Stream selbst zurück, sodass ihr Ergebnis per Pipeline weitergeleitet werden kann. Diese Operationen werden als Zwischenoperationen bezeichnet und ihre Funktion besteht darin, Eingaben entgegenzunehmen, sie zu verarbeiten und die Ausgabe an das Ziel zurückzugeben. Die Methode collect() ist eine Terminaloperation, die normalerweise am Ende der Pipelining-Operation vorhanden ist, um das Ende des Streams zu markieren.
-
Automatische Iterationen − Stream-Operationen führen die Iterationen intern über die bereitgestellten Quellelemente durch, im Gegensatz zu Sammlungen, bei denen eine explizite Iteration erforderlich ist.
Streams generieren
Mit Java 8 verfügt die Collection-Schnittstelle über zwei Methoden zum Generieren eines Streams.
-
stream() − Gibt einen sequentiellen Stream zurück, der die Sammlung als Quelle berücksichtigt.
-
parallelStream() − Gibt einen parallelen Stream zurück, der eine Sammlung als Quelle berücksichtigt.
List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl"); List<String> filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());
für jeden
Stream hat eine neue Methode „forEach“ bereitgestellt, um jedes Element des Streams zu durchlaufen. Das folgende Codesegment zeigt, wie 10 Zufallszahlen mit forEach ausgegeben werden.
Random random = new Random(); random.ints().limit(10).forEach(System.out::println);
Karte
Die „map“-Methode wird verwendet, um jedes Element seinem entsprechenden Ergebnis zuzuordnen. Das folgende Codesegment druckt mithilfe von map.
eindeutige ZahlenquadrateList<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5); //get list of unique squares List<Integer> squaresList = numbers.stream().map( i -> i*i).distinct().collect(Collectors.toList());
filtern
Die „Filter“-Methode wird verwendet, um Elemente basierend auf einem Kriterium zu eliminieren. Das folgende Codesegment gibt mithilfe von filter.
eine Anzahl leerer Zeichenfolgen ausList<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl"); //get count of empty string int count = strings.stream().filter(string -> string.isEmpty()).count();
Grenze
Die „Limit“-Methode wird verwendet, um die Größe des Streams zu reduzieren. Das folgende Codesegment zeigt, wie man 10 Zufallszahlen mit limit.
ausgibtRandom random = new Random(); random.ints().limit(10).forEach(System.out::println);
sortiert
Die Sortiermethode wird verwendet, um den Stream zu sortieren. Das folgende Codesegment zeigt, wie 10 Zufallszahlen in sortierter Reihenfolge ausgegeben werden.
Random random = new Random(); random.ints().limit(10).sorted().forEach(System.out::println);
Parallele Verarbeitung
parallelStream ist die Alternative von stream für parallele Verarbeitung. Sehen Sie sich das folgende Codesegment an, das mithilfe von parallelStream eine Anzahl leerer Zeichenfolgen ausgibt.
List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl"); //get count of empty string long count = strings.parallelStream().filter(string -> string.isEmpty()).count();
Es ist sehr einfach, zwischen sequentiellen und parallelen Streams umzuschalten.
Sammler
Kollektoren werden verwendet, um das Ergebnis der Verarbeitung der Elemente eines Streams zu kombinieren. Kollektoren können verwendet werden, um eine Liste oder einen String zurückzugeben.
List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl"); List<String> filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList()); System.out.println("Filtered List: " + filtered); String mergedString = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.joining(", ")); System.out.println("Merged String: " + mergedString);
Statistiken
Mit Java 8 werden Statistiksammler eingeführt, um alle Statistiken zu berechnen, wenn die Stream-Verarbeitung durchgeführt wird.
List numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5); IntSummaryStatistics stats = numbers.stream().mapToInt((x) -> x).summaryStatistics(); System.out.println("Highest number in List : " + stats.getMax()); System.out.println("Lowest number in List : " + stats.getMin()); System.out.println("Sum of all numbers : " + stats.getSum()); System.out.println("Average of all numbers : " + stats.getAverage());
Stream-Beispiel
Erstellen Sie das folgende Java-Programm mit einem beliebigen Editor Ihrer Wahl in beispielsweise C:\> JAVA.
Java8Tester.java
Live-Demoimport java.util.ArrayList; import java.util.Arrays; import java.util.IntSummaryStatistics; import java.util.List; import java.util.Random; import java.util.stream.Collectors; import java.util.Map; public class Java8Tester { public static void main(String args[]) { System.out.println("Using Java 7: "); // Count empty strings List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl"); System.out.println("List: " +strings); long count = getCountEmptyStringUsingJava7(strings); System.out.println("Empty Strings: " + count); count = getCountLength3UsingJava7(strings); System.out.println("Strings of length 3: " + count); //Eliminate empty string List<String> filtered = deleteEmptyStringsUsingJava7(strings); System.out.println("Filtered List: " + filtered); //Eliminate empty string and join using comma. String mergedString = getMergedStringUsingJava7(strings,", "); System.out.println("Merged String: " + mergedString); List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5); //get list of square of distinct numbers List<Integer> squaresList = getSquares(numbers); System.out.println("Squares List: " + squaresList); List<Integer> integers = Arrays.asList(1,2,13,4,15,6,17,8,19); System.out.println("List: " +integers); System.out.println("Highest number in List : " + getMax(integers)); System.out.println("Lowest number in List : " + getMin(integers)); System.out.println("Sum of all numbers : " + getSum(integers)); System.out.println("Average of all numbers : " + getAverage(integers)); System.out.println("Random Numbers: "); //print ten random numbers Random random = new Random(); for(int i = 0; i < 10; i++) { System.out.println(random.nextInt()); } System.out.println("Using Java 8: "); System.out.println("List: " +strings); count = strings.stream().filter(string->string.isEmpty()).count(); System.out.println("Empty Strings: " + count); count = strings.stream().filter(string -> string.length() == 3).count(); System.out.println("Strings of length 3: " + count); filtered = strings.stream().filter(string ->!string.isEmpty()).collect(Collectors.toList()); System.out.println("Filtered List: " + filtered); mergedString = strings.stream().filter(string ->!string.isEmpty()).collect(Collectors.joining(", ")); System.out.println("Merged String: " + mergedString); squaresList = numbers.stream().map( i ->i*i).distinct().collect(Collectors.toList()); System.out.println("Squares List: " + squaresList); System.out.println("List: " +integers); IntSummaryStatistics stats = integers.stream().mapToInt((x) ->x).summaryStatistics(); System.out.println("Highest number in List : " + stats.getMax()); System.out.println("Lowest number in List : " + stats.getMin()); System.out.println("Sum of all numbers : " + stats.getSum()); System.out.println("Average of all numbers : " + stats.getAverage()); System.out.println("Random Numbers: "); random.ints().limit(10).sorted().forEach(System.out::println); //parallel processing count = strings.parallelStream().filter(string -> string.isEmpty()).count(); System.out.println("Empty Strings: " + count); } private static int getCountEmptyStringUsingJava7(List<String> strings) { int count = 0; for(String string: strings) { if(string.isEmpty()) { count++; } } return count; } private static int getCountLength3UsingJava7(List<String> strings) { int count = 0; for(String string: strings) { if(string.length() == 3) { count++; } } return count; } private static List<String> deleteEmptyStringsUsingJava7(List<String> strings) { List<String> filteredList = new ArrayList<String>(); for(String string: strings) { if(!string.isEmpty()) { filteredList.add(string); } } return filteredList; } private static String getMergedStringUsingJava7(List<String> strings, String separator) { StringBuilder stringBuilder = new StringBuilder(); for(String string: strings) { if(!string.isEmpty()) { stringBuilder.append(string); stringBuilder.append(separator); } } String mergedString = stringBuilder.toString(); return mergedString.substring(0, mergedString.length()-2); } private static List<Integer> getSquares(List<Integer> numbers) { List<Integer> squaresList = new ArrayList<Integer>(); for(Integer number: numbers) { Integer square = new Integer(number.intValue() * number.intValue()); if(!squaresList.contains(square)) { squaresList.add(square); } } return squaresList; } private static int getMax(List<Integer> numbers) { int max = numbers.get(0); for(int i = 1;i < numbers.size();i++) { Integer number = numbers.get(i); if(number.intValue() > max) { max = number.intValue(); } } return max; } private static int getMin(List<Integer> numbers) { int min = numbers.get(0); for(int i= 1;i < numbers.size();i++) { Integer number = numbers.get(i); if(number.intValue() < min) { min = number.intValue(); } } return min; } private static int getSum(List numbers) { int sum = (int)(numbers.get(0)); for(int i = 1;i < numbers.size();i++) { sum += (int)numbers.get(i); } return sum; } private static int getAverage(List<Integer> numbers) { return getSum(numbers) / numbers.size(); } }
Überprüfen Sie das Ergebnis
Kompilieren Sie die Klasse mit javac Compiler wie folgt −
C:\JAVA>javac Java8Tester.java
Führen Sie nun den Java8Tester wie folgt aus −
C:\JAVA>java Java8Tester
Es sollte das folgende Ergebnis erzeugen −
Using Java 7: List: [abc, , bc, efg, abcd, , jkl] Empty Strings: 2 Strings of length 3: 3 Filtered List: [abc, bc, efg, abcd, jkl] Merged String: abc, bc, efg, abcd, jkl Squares List: [9, 4, 49, 25] List: [1, 2, 13, 4, 15, 6, 17, 8, 19] Highest number in List : 19 Lowest number in List : 1 Sum of all numbers : 85 Average of all numbers : 9 Random Numbers: -1279735475 903418352 -1133928044 -1571118911 628530462 18407523 -881538250 -718932165 270259229 421676854 Using Java 8: List: [abc, , bc, efg, abcd, , jkl] Empty Strings: 2 Strings of length 3: 3 Filtered List: [abc, bc, efg, abcd, jkl] Merged String: abc, bc, efg, abcd, jkl Squares List: [9, 4, 49, 25] List: [1, 2, 13, 4, 15, 6, 17, 8, 19] Highest number in List : 19 Lowest number in List : 1 Sum of all numbers : 85 Average of all numbers : 9.444444444444445 Random Numbers: -1009474951 -551240647 -2484714 181614550 933444268 1227850416 1579250773 1627454872 1683033687 1798939493 Empty Strings: 2
Java