Advanced Java Services | Streams erzeugen und bearbeiten |
Man kann praktisch jede Sammlung von Daten "streamen". Hier einige Beispiele.
Wir verwenden ein einfaches int-Array.
int[] intArr = {15, 24, 33, 42, 51, 65, 74, 83, 92, 21};
Und filtern daraus die ungeraden Zahlen (zunächst ausführlich).
IntStream intStream = Arrays.stream(intArr); IntPredicate oddFilter = i -> i%2 == 1 ; // Typ und runde Klammern können weggelassen werden IntStream filtered = intStream.filter(oddFilter); IntConsumer intConsumer = i -> System.out.println(i) ; filtered.forEach(intConsumer);
Und nun die Kurzfassung als Aggregat.
Arrays.stream(intArr).filter( i -> i%2 == 1 ).forEach( i -> System.out.println(i) );
Interessanterweise kann man hier auch mit einem Objectstream arbeiten. Zunächst wieder ausführlich.
StreamintegerStream = Arrays.stream( integerArr ); Predicate oddPredicate = i -> i%2 == 1 ; Stream filteredStream = integerStream.filter(oddPredicate); Consumer integerConsumer = i -> System.out.println(i) ; filteredStream.forEach(integerConsumer);
Die Kurzfassung in einer Zeile.
Arrays.stream(integerArr).filter( i -> i%2 == 1 ).forEach( i -> System.out.println(i) );
Wir lesen eine Datei "years.txt" ein, die zeilenweise die Jahreszahlen von 1900 - 1930 enthält. Aus den eingelesenen Jahreszahlen wollen wir die Schaltjahre herausfischen (einfache Schaltjahresregel!).
Zunächst die ausführliche Fassung
try (BufferedReader br = new BufferedReader(new FileReader("years.txt")) ) { //Langfassung Stream<String> lineStream = br.lines(); Predicate<String> leapyearFilter = line -> Integer.valueOf(line) %4 == 0 ; Stream<String> filteredStream = lineStream.filter(leapyearFilter); Consumer<String> stringConsumer = st -> System.out.println(st) ; filteredStream.forEach(stringConsumer); } catch(IOException ex) { System.out.println(ex); }
Und nun der Oneliner.
try (BufferedReader br = new BufferedReader(new FileReader("years.txt")) ) { //Kurzfassung br.lines().filter( (String line) -> Integer.valueOf(line) %4 == 0 ).forEach( st -> System.out.println(st)); //oder //br.lines().filter( line -> Integer.valueOf(line.toString()) %4 == 0 ).forEach( System.out::println )); //fehlt die Typangabe in der Parameterliste setzt der Compiler Object als Typ ! } catch(IOException ex) { System.out.println(ex); }
Wir lesen wieder über einen Stream ein und wollen die Schaltjahresstrings in eine ArrayList bringen.
private static void bufferedReader2() { try (BufferedReader br = new BufferedReader(new FileReader("years.txt")) ) { ArrayList<String-> leapYearList = new ArrayList<->(); br.lines().filter( (String line) -> Integer.valueOf(line) %4 == 0 ).forEach( st -> leapYearList.add(st) ); System.out.println(leapYearList); } catch(IOException ex) { System.out.println(ex); } }
Wir können also aus dem Lambdaausdruck heraus auf Variablen zugreifen, in diesem Fall auf die ArrayList. Besseres Design ist allerdings, solche Zugriffe zu vermeiden. Das nächste Beispiel zeigt, daß das sehr einfach möglich ist.
private static void bufferedReader3() { try (BufferedReader br = new BufferedReader(new FileReader("years.txt")) ) { //ArrayList<String> leapYearList = new ArrayList<>(); List<String> leapYearList = br.lines().filter( (String line) -> Integer.valueOf(line) %4 == 0 ).collect(Collectors.toList()); System.out.println(leapYearList); } catch(IOException ex) { System.out.println(ex); } }
Das Streamen verläuft im Grunde genauso wie bei Arrays. Wir erstellen eine ArrayList von Integer und lesen daraus die ungeraden Zahlen aus.
List<Integer> intList = Arrays.asList(15, 24, 33, 42, 51, 65, 74, 83, 92, 21); System.out.println(intList); intList.stream().filter( i -> i%2 == 1 ).forEach( i -> System.out.println(i) );