У гэтым паведамленні ў блогу мы абмяркуем асаблівасці Java 8 Streams і прадставім мноства розных прыкладаў кода.
Java Streams забяспечваюць функцыянальнае праграмаванне ў Java, і яны падтрымліваюцца, пачынаючы з Java 8, таму, калі ў вас старая версія Java, вам трэба перайсці на java 8, каб выкарыстоўваць Java Streams.
Некаторыя перавагі патокаў:
У большасці выпадкаў трубаправод патокаў складаецца з
Крыніца збіраецца трансліраваць паток элементаў.
Гэты паток элементаў можна адфільтраваць, адсартаваць, адлюстраваць альбо нанесці іншы шэраг аперацый, якія прымяняюцца да кожнага элемента.
У рэшце рэшт, гэта можа быць альбо збор, альбо памяншэнне, альбо нейкая іншая аперацыя тэрмінала, але выконваецца толькі адна аперацыя тэрмінала.
Крыніца патоку можа паходзіць з калекцый, спісаў, набораў, масіваў int, longs, double, радкоў і г.д.
Патоковыя аперацыі альбо прамежкавыя, альбо канчатковыя:
Некаторыя прамежкавыя аперацыі ўключаюць:
Дапускаецца толькі адна аперацыя тэрмінала.
Некалькі прыкладаў функцый скарачэння:
Зараз давайце паглядзім вышэйзгаданыя паняцці на прыкладах кода.
Першы прыклад - проста цэлы паток. Мы збіраемся стварыць цэлалікавы паток, выкарыстоўваючы IntStream
клас і яго функцыя дыяпазону, якая дае нам цэлы шэраг.
forEach
гэта наш тэрмінал. Для кожнага элемента мы проста збіраемся раздрукаваць яго.
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();
} }
Выхад:
123456789
У другім прыкладзе выкарыстоўваецца цэлы паток, але мы дадалі skip()
вось, у гэтым выпадку мы збіраемся прапусціць першыя 5 элементаў нашага патоку.
Гэта будзе друкаваць толькі элементы з 6 па 9. Мы таксама выкарыстоўваем просты лямбда-выраз для раздрукоўкі элемента
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();
} }
Выхад:
6 7 8 9
Трэці прыклад, мы зноў выкарыстоўваем IntStream
аднак, каб стварыць наш паток аб'ектаў, мы змяшчаем яго ў println()
аператар як параметр для радка друку.
Тое, што мы збіраемся надрукаваць, гэта проста сума ад 1 да 5, іншымі словамі, 1 2 3 і 4, яна будзе выводзіць толькі суму гэтых лічбаў:
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();
} }
Выхад:
10
У наступным прыкладзе выкарыстоўваецца Stream.of
функцыя, што вельмі зручна, таму што вы можаце перадаваць цэлыя лікі, значэнні з плаваючай кропкай, радкі і нават аб'екты.
У гэтым прыкладзе мы проста зробім прамы алфавітны сартаванне, пасля чаго знойдзем першы элемент, выкарыстоўваючы findFirst()
функцыя. Затым мы проста раздрукоўваем першы пункт у спісе.
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);
} }
Выхад
Alberto
У наступным прыкладзе мы збіраемся трансліраваць з масіва. Тады мы будзем сартаваць, фільтраваць, а потым раздрукоўваць.
Тут мы адфільтруем элементы, якія пачынаюцца з s
.
Мы выкарыстоўваем лямбда-выраз, які прымае X
гэта кожнае імя, а потым правяраецца, якое пачынаецца з літары s
і гэта перадасць.
Тады мы будзем сартаваць іх, а затым для кожнага элемента, які праходзіць гэты сартаванне, мы надрукуем яго.
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);
} }
Выхад:
Sarah Sarika Shivika
Зараз давайце паглядзім, як мы можам прыняць сярэдняе значэнне квадратаў масіва int.
Тут мы выкарыстоўваем Arrays.stream()
функцыя для перадачы цэлых лікаў, і тады мы будзем выкарыстоўваць map()
для супастаўлення кожнага элемента з цэлым лікам да яго квадрата.
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);
} }
Выхад:
44.0
Звярніце ўвагу, што ён выводзіць двайны замест цэлага ліку.
У гэтым прыкладзе мы збіраемся трансляваць са спісу, фільтраваць гэтыя элементы, а потым раздрукоўваць.
Звярніце ўвагу, што ў межах map()
функцыя, мы збіраемся пераўтварыць усе імёны ў малую.
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);
} }
Выхад:
al ankit amanda
Мы бачым, што ў нас ёсць тры назвы, якія пачынаюцца з a
і ўсе яны ў маленькай літары.
У наступным прыкладзе мы збіраемся трансліраваць радкі з тэкставага файла. Мы збіраемся сартаваць, фільтраваць і раздрукоўваць.
Дапусцім, у нас ёсць файл, які называецца bands.txt
са зместам, паказаным ніжэй:
Rolling Stones Lady Gaga Jackson Browne Maroon 5 Arijit Singh Elton John John Mayer CCR Eagles Pink Aerosmith Adele Taylor Swift
Мы будзем выкарыстоўваць Files.lines()
каб стварыць наш паток, які збіраецца даць нам паток радка для кожнага радка файла.
Пасля таго, як у нас ёсць паток, мы адсартуем іх і адфільтруем элементы, якія перавышаюць 13 сімвалаў, а затым раздрукуем тыя, што засталіся.
Нарэшце, мы павінны закрыць файл, таму мы робім 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();
} }
Выхад:
Jackson Browne Rolling Stones
Мы атрымліваем дзве групы, якія маюць больш за 13 сімвалаў.
У гэтым прыкладзе мы будзем выкарыстоўваць той жа тэкставы файл, што і вышэй.
Мы хочам адфільтраваць элементы, якія ўтрымліваюць літары jit
, выкарыстоўваючы x.contains()
што проста функцыя радка.
Выкарыстанне .collect()
дадаем усе з літарамі jit
у спіс.
Пасля таго, як у нас ёсць спіс, мы можам выкарыстоўваць forEach
аператар для раздрукоўкі элементаў.
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));
} }
Выхад:
Arijit Singh
У гэтым прыкладзе мы трансліруем радкі з файла CSV і збіраемся падлічыць добрыя радкі.
Дапусцім, у нас ёсць файл, які называецца data.txt
са наступным зместам:
A,12,3.7 B,17,2.8 C,14,1.9 D,23,2.7 E F,18,3.4
Тут радок E не мае дадзеных, таму мы хочам выключыць гэты з нашага патоку.
У наступным кодзе мы будзем чытаць у кожным радку, пасля чаго нам трэба падзяліць коскі на масіў, каб кожны радок стаў масівам элементаў.
Затым мы ўжываем фільтр для фільтрацыі радкоў, у якіх няма трох элементаў.
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();
} }
Выхад:
5 rows
Гэты прыклад паказвае, як выкарыстоўваць памяншэнне. Мы збіраемся скараціць да сумы. Тут мы маем двайны паток з выкарыстаннем Stream.of()
функцыя. Мы вызначылі тры дублі ў трох розных аргументах і будзем выкарыстоўваць функцыю скарачэння.
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);
} }
Выхад:
13.600000000000001