Selles blogipostituses käsitleme Java 8 voogude funktsioone ja pakume palju erinevaid koodinäiteid.
Java voogud toovad Java-sse funktsionaalse programmeerimise ja neid toetatakse alates java 8-st, nii et kui teil on Java-versioon vanem, peate Java-voogude kasutamiseks täiendama Java 8-le.
Mõned voogude eelised:
Enamasti koosneb ojaga torujuhe a
Allikas hakkab voogesitama elementide voogu.
Seda elementide voogu saab filtreerida, sorteerida või kaardistada või rakendada igale elemendile erinevaid muid toimingute seeriaid.
Lõpus saab seda kas koguda või vähendada või teha mõne muu terminali operatsiooni, kuid tehakse ainult üks terminali toiming.
Voo allikas võivad pärineda kogudest, loenditest, komplektidest, int-de, pikkade, topeltide, stringide jne massiividest
Voogesitustoimingud on kas vahepealsed või terminalid:
Mõned vaheoperatsioonid hõlmavad järgmist:
Lubatud on ainult ühe terminali hankimine.
Mõned näited vähendusfunktsioonidest on:
Vaatame nüüd ülaltoodud mõisteid koodinäidetes.
Esimene näide on lihtsalt täisarvu voog. Loome IntStream
abil täisarvu voo klass ja selle vahemiku funktsioon, mis annab meile hulga täisarvusid.
forEach
on meie terminali töö. Iga üksuse jaoks printime selle lihtsalt välja.
import java.io.IOException; import java.util.stream.IntStream; public class JavaStreams {
public static void main(String[] args) throws IOException {
IntStream
.range(1, 10)
.forEach(System.out::print);
System.out.println();
} }
Väljund:
123456789
Teises näites kasutatakse täisarvu voogu, kuid lisasime skip()
siin, nii et sel juhul jätame oma voo esimesed 5 elementi vahele.
See on ainult elementide 6–9 printimine. Üksuse printimiseks kasutame ka lihtsat lambda-väljendit
import java.io.IOException; import java.util.stream.IntStream; public class JavaStreams {
public static void main(String[] args) throws IOException {
IntStream
.range(1, 10)
.skip(5)
.forEach(x -> System.out.println(x));
System.out.println();
} }
Väljund:
6 7 8 9
Kolmas näide, kasutame jällegi IntStream
objektide voo loomiseks panime selle println()
sisse lause trükirea parameetrina.
See, mida me printime, on ainult summa vahemikus 1–5 ehk 1 2 3 ja 4 prindib välja ainult nende arvude summa:
import java.io.IOException; import java.util.stream.IntStream; public class JavaStreams {
public static void main(String[] args) throws IOException {
System.out.println(
IntStream
.range(1, 5)
.sum());
System.out.println();
} }
Väljund:
10
Järgmine näide kasutab Stream.of
funktsioon, mis on tõesti mugav, kuna saate voogesitada täisarvusid, ujukoma väärtusi või stringe või isegi objekte.
Selles näites teeme lihtsalt sirgjoonelise tähestikulise järjestuse, seejärel leiame esimese üksuse, kasutades findFirst()
funktsioon. Seejärel printime lihtsalt loendi esimese üksuse välja.
import java.io.IOException; import java.util.stream.Stream; public class JavaStreams {
public static void main(String[] args) throws IOException {
Stream.of('Ava', 'Aneri', 'Alberto')
.sorted()
.findFirst()
.ifPresent(System.out::println);
} }
Väljund
Alberto
Järgmises näites voogesitame massiivist. Seejärel sorteerime, filtreerime ja siis printime.
Filtreerime siin ainult üksused, mis algavad tähtedega s
Kasutame lambda väljendit, mis võtab sisse X
mis on iga nimi ja siis kontrollitakse, millised algavad tähega s
ja see annab need edasi.
Seejärel sorteerime need ja siis printime selle iga üksuse jaoks, mis selle sordi läbib.
import java.io.IOException; import java.util.Arrays; public class JavaStreams {
public static void main(String[] args) throws IOException {
String[] names = {'Al', 'Ankit', 'Kushal', 'Brent', 'Sarika', 'amanda', 'Hans', 'Shivika', 'Sarah'};
Arrays.stream(names)
.filter(x -> x.startsWith('S'))
.sorted()
.forEach(System.out::println);
} }
Väljund:
Sarah Sarika Shivika
Vaatame nüüd, kuidas saaksime int-massiivi ruutude keskmist võtta.
Siin kasutame Arrays.stream()
täisarvude voogesitamiseks ja siis hakkame kasutama map()
iga üksuse iga täisarvu kaardistamiseks oma ruuduga.
import java.util.Arrays; public class JavaStreams {
public static void main(String[] args) {
Arrays.stream(new int[] {2, 4, 6, 8, 10})
.map(x -> x * x)
.average()
.ifPresent(System.out::println);
} }
Väljund:
44.0
Pange tähele, et see prinditakse täisarvu asemel topelt.
Selles näites voogesitame loendist, filtreerime need üksused ja seejärel printime.
Pange tähele, et map()
funktsiooni, teisendame kõik nimed väiketähtedeks.
import java.util.Arrays; import java.util.List; public class JavaStreams {
public static void main(String[] args) {
List people = Arrays.asList('Al', 'Ankit', 'Brent', 'Sarika', 'amanda', 'Hans', 'Shivika', 'Sarah');
people
.stream()
.map(String::toLowerCase)
.filter(x -> x.startsWith('a'))
.forEach(System.out::println);
} }
Väljund:
al ankit amanda
Näeme, et meil on kolm nime, mis algavad a
ja nad kõik on väiketähtedega.
Järgmises näites voogesitame read tekstifailist. Me hakkame sortima, filtreerima ja printima.
Oletame, et meil on fail nimega bands.txt
allpool näidatud sisuga:
Rolling Stones Lady Gaga Jackson Browne Maroon 5 Arijit Singh Elton John John Mayer CCR Eagles Pink Aerosmith Adele Taylor Swift
Kasutame Files.lines()
meie voo loomiseks, mis annab meile faili iga rea jaoks stringi voo.
Kui voog on käes, sorteerime need ja filtreerime välja üksused, mis on pikemad kui 13 tähemärki, ja printime siis järelejäänud üksused.
Lõpuks peame faili sulgema, nii et teeme bands.close
import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.stream.Stream; public class JavaStreams {
public static void main(String[] args) throws IOException {
Stream bands = Files.lines(Paths.get('bands.txt'));
bands
.sorted()
.filter(x -> x.length() > 13)
.forEach(System.out::println);
bands.close();
} }
Väljund:
Jackson Browne Rolling Stones
Saame kaks ansamblit, millel on rohkem kui 13 tähemärki.
Selle näite puhul kasutame sama tekstifaili nagu eespool.
Soovime filtreerida üksused, mis sisaldavad tähti jit
, kasutades x.contains()
mis on lihtsalt stringi funktsioon.
Kasutades .collect()
liidame kõik tähtedega jit
loendisse.
Kui nimekiri on väljas, saame seejärel kasutada nuppu forEach
operaator üksuste printimiseks.
import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.List; import java.util.stream.Collectors; public class JavaStreams {
public static void main(String[] args) throws IOException {
List bands2 = Files.lines(Paths.get('bands.txt'))
.filter(x -> x.contains('jit'))
.collect(Collectors.toList());
bands2.forEach(x -> System.out.println(x));
} }
Väljund:
Arijit Singh
Selles näites voogesitame ridu CSV-failist ja loeme häid ridu.
Oletame, et meil on fail nimega data.txt
järgmise sisuga:
A,12,3.7 B,17,2.8 C,14,1.9 D,23,2.7 E F,18,3.4
Siin pole real E andmeid, seega tahame selle oma voost välja jätta.
Järgmises koodis loeme igas reas, siis peame komades jagama massiiviks, nii et igast reast saab üksuste massiiv.
Seejärel rakendame filtri, et välja filtreerida read, millel pole kolme üksust.
import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.stream.Stream; public class JavaStreams {
public static void main(String[] args) throws IOException {
Stream rows1 = Files.lines(Paths.get('data.txt'));
int rowCount = (int)rows1
.map(x -> x.split(','))
.filter(x -> x.length == 3)
.count();
System.out.println(rowCount + ' rows.');
rows1.close();
} }
Väljund:
5 rows
See näide näitab, kuidas reduktsiooni kasutada. Taandame summa. Siin on meil topeltvoog, kasutades Stream.of()
funktsioon. Oleme määranud kolm duublit kolmes erinevas argumendis ja kasutame funktsiooni redutseerimine.
import java.util.stream.Stream; public class JavaStreams {
public static void main(String[] args) {
double total = Stream.of(7.3, 1.5, 4.8)
.reduce(0.0, (Double a, Double b) -> a + b);
System.out.println('Total = ' + total);
} }
Väljund:
13.600000000000001