Stream API дегеніміз не?
Stream API функционалдық стильде деректер құрылымдарымен жұмыс істеудің жаңа тәсілі болып табылады. Stream API (бір компьютерлік бағдарламаның басқа бағдарламамен байланысу тәсілдерінің сипаттамасы) оның негізінде деректер ағыны болып табылады. Жалпы бағдарламалауда, атап айтқанда Java тілінде «жіп» терминінің өзі анық емес.List<String> list = new ArrayList<String>();
list.add("One");
list.add("Two");
list.add("Three");
list.add("Four");
list.add("Five");
list.add("Six");
list.add("Seven");
list.add("Eight");
list.add("Nine");
list.add("Ten");
Stream stream = list.stream();
Жоғарыда айтылғандай, Stream API code жолдарының санын азайтуға мүмкіндік береді. Ағынмен мысал:
IntStream.of(50, 60, 70, 80, 90, 100, 110, 120).filter(x -> x < 90).map(x -> x + 10)
.limit(3).forEach(System.out::print);
Жіпсіз мысал:
int[] arr = {50, 60, 70, 80, 90, 100, 110, 120
int count = 0;
for (int x : arr) {
if (x >= 90) continue;
x += 10;
count++;
if (count > 3) break;
System.out.print(x);
}
Ағынды құрудың мүмкін жолдары:
- Бос ағын:
Stream.empty()
- Тізімнен ағын:
list.stream()
- Картадан ағын:
map.entrySet().stream()
- Массивтен ағын:
Arrays.stream(array)
- Көрсетілген элементтерден ағын:
Stream.of("1", "2", "3")
- Аралық («жалқау» деп те аталады) - кіріс элементтерді өңдейді және ағынды қайтарады. Элементтерді өңдеу тізбегінде көптеген аралық операторлар болуы мүмкін.
- Терминал («терминал», «құмарлық» деп те аталады) - элементтерді өңдейді және ағынды тоқтатады, сондықтан тізбекте бір ғана терминал операторы болуы мүмкін.
1.List<String> list = new ArrayList<String>();
2.list.add("One");
…
11.list.add("Ten");
12.Stream stream = list.stream();
13.stream.filter(x-> x.toString().length() == 3).forEach(System.out::println);
Бұл жерде не болып жатыр:
- 1 - тізім құру
list
; - 2-11 – оны сынақ деректерімен толтыру;
- 12 - an object құру
Stream
; - 13 - әдіс
filter
(сүзгі) - аралық оператор,x
санау үшін жинақтың бір элементіне теңестіреді (мен сияқтыfor each
) және -> кейін біз коллекциямыз қалай сүзілгенін көрсетеміз және бұл аралық оператор болғандықтан, сүзілген жинақ әдіске одан әрі өтеді ,forEach
бұл өз кезегінде санаудың терминалдық (соңғы) аналогыfor each
(System.out::println
Қысқа өрнек:,x-> System.out.println(x))
ол өз кезегінде оған берілген жинақтың барлық элементтерінен өтіп, оны көрсетеді)
- Терминал операторы шақырылмайынша өңдеу басталмайды.
list.stream().filter(s -> s > 5)
(тізімнен бірде-бір элемент алынбайды); - Ағынның данасын бір реттен артық пайдалануға болмайды =( ;
Сондықтан, ол жаңа болған сайын:
list.stream().filter(x-> x.toString().length() == 3).forEach(System.out::println);
list.stream().forEach(x -> System.out.println(x));
Бір ғана терминал операторы бар болса, бір ағынға шақырылатын көптеген аралық операторлар болуы мүмкін:
stream.filter(x-> x.toString().length() == 3).map(x -> x + " - the length of the letters is three").forEach(x -> System.out.println(x));
filter(Predicate predicate)
Шартты тапсыратын элементтерді ғана өткізіп, ағынды сүзеді (Predicate — Java SE 8 пакетіне қосылған кірістірілген функционалды интерфейс. « true » және « falsejava.util.function
» мәнін тексереді );map(Function mapper)
әрбір элементті өзгертетін және оны әрі қарай өткізіп жіберетін функцияны жасауға мүмкіндік береді (Функционалдық интерфейсFunction<T,R>
T типті an objectіден R түріндегі an objectіге өту функциясын білдіреді)flatMap(Function<T, Stream<R>> mapper)
- жағдайындағыдайmap
олар қарабайыр ағынға түрлендіру үшін қолданылады.
[stream1,stream2,stream3,stream4] => stream
:
String[] array = {"Java", "Ruuuuussshhh"};
Stream<String> streamOfArray = Arrays.stream(array);
streamOfArray.map(s->s.split("")) //Convert the word to an array of letters
.flatMap(Arrays::stream).distinct() //aligns each generated thread into a single thread
.collect(Collectors.toList()).forEach(System.out::println);
map
Ол ағындар тізіміне түрлендіру кезінде (дәлірек <Stream>
ағындар) [stream1,stream2,stream3,stream4] =>Stream.of(stream1,stream2,stream3,stream4)
:
String[] array = {"Java", "Ruuuuussshhh"};
Stream<String> streamOfArray = Arrays.stream(array);
streamOfArray.map(s->s.split("")) //Convert the word to an array of letters
.map(Arrays::stream).distinct() //Make the array into a separate thread
.collect(Collectors.toList()).forEach(System.out::println);
-мен салыстырғанда тағы бір айырмашылық map
, сіз бір элементті нөлге, біреуге немесе көптеген басқаларға түрлендіруге болады. Бір элементті нөлдік элементтерге түрлендіру үшін , null
немесе бос ағынды қайтару қажет. Бір элементке түрлендіру үшін бір элементтен ағынды қайтару керек, мысалы, арқылы Stream.of(x)
. Бірнеше элементтерді қайтару үшін кез келген тәсілмен осы элементтермен ағын жасауға болады. Бірдей flatMap әдісі, бірақ Double, Integer және Long үшін:
- flatMapToDouble(Функция салыстырушы)
- flatMapToInt(Функция салыстырушы)
- flatMapToLong(Функция салыстырушы)
Stream.of(2, 3, 0, 1, 3)
.flatMapToInt(x -> IntStream.range(0, x))
.forEach(System.out::print);// 010120012
-
IntStream.range(0,x) – 0 (қоса) бастап x (қоса емес) аралығындағы элементтерді ағынға шығарады;
карта:
Stream.of(2, 3, 0, 1, 3) .map(x -> IntStream.range(0, x)) .forEach(System.out::print);//list of streams (streams);
-
limit(long maxSize) – ағынды элементтер саны бойынша шектейді:
stream.limit(5).forEach(x -> System.out.println(x));
-
skip(long n) – n элементті өткізіп жіберу:
stream.skip(3).forEach(x -> System.out.println(x));
-
сұрыпталған()
- сұрыпталған(Салыстырғыш компараторы) – ағынды сұрыптайды (TreeMap сияқты сұрыптау):
stream.sorted().forEach(x -> System.out.println(x));
-
distinct() — элементтердің бірегейлігі үшін ағынды тексереді (элементтердің қайталануын жояды);
-
dropWhile(Predicate предикаты) – шартты қанағаттандыратын элементтерді өткізіп жібереді (java 9-да пайда болды, Predicate<T> функционалдық интерфейсі қандай да бір шарттың орындалғанын тексереді. Егер ол орындалса, онда шын мәні қайтарылады. Lambda өрнегі типтегі нысанды қабылдайды. T параметр ретінде:
Predicate<Integer> isPositive = x -> x > 0; System.out.println(isPositive.test(3)); // true System.out.println(isPositive.test(-9)); // false
-
forEach(Тұтынушы әрекеті) – әрқайсысы үшін аналогы (Тұтынушы<T> ештеңені қайтармай, T түріндегі an objectіде қандай да бір әрекетті орындайды);
-
count() – ағын элементтерінің санын қайтарады:
System.out.println(stream.count());
-
жинау(Коллектор жинағыш) – әдіс барлық элементтерді тізімге, жиынтыққа немесе басқа жинаққа жинайды, элементтерді қандай да бір критерий бойынша топтайды, барлығын жолға біріктіреді және т.б.:
List<String> list = Stream.of(“One”, “Two”, “Three”).collect(Collectors.toList());
-
collect(Supplier supplier, BiConsumer accumulator, BiConsumer combiner)
— сияқты,collect(collector)
ыңғайлы болу үшін тек параметрлері бөлінеді (supplier
жаңа an objectілерді (контейнерлерді) береді, мысалыnew ArrayList()
,accumulator
контейнерге элемент қосады,combiner
ағынның бөліктерін біріктіреді); -
азайту(T идентификаторы, BinaryOperator аккумуляторы) – ағынның барлық элементтерін бір an objectіге түрлендіреді (барлық элементтердің қосындысын есептеңіз немесе минималды элементті табыңыз), алдымен an object
identity
және ағынның бірінші элементі алынады, функция қолданыладыaccumulator
жәнеidentity
оның нәтижесі болады. Содан кейін қалған элементтер үшін бәрі жалғасады.int sum = Stream.of(1, 2, 3, 4, 5).reduce(10, (acc, x) -> acc + x);// = 25
-
reduce(BinaryOperator accumulator)
— жоғарыдағы әдіспен бірдей, бірақ бастапқысы жоқidentity
, бұл ағынның бірінші элементіOptional min(Comparator comparator)
Қосымша max(Comparator comparator) берілген компаратор негізінде минималды/максималды элементті іздейді; -
findFirst()
– ағынның бірінші элементін шығарады:Stream.of(1, 2, 3, 4, 9).findFirst();
-
allMatch(Predicate predicate)
— егер ағынның барлық элементтері шартты қанағаттандырса, true мәнін қайтарады. Егер предикат функциясын шақыру нәтижесі жалған болатын кез келген элемент кездессе , онда оператор элементтерді сканерлеуді тоқтатады және жалған мәнін қайтарады :Stream.of(1, 2, 3, 4, 9).allMatch(x -> x <= 7);//false
-
anyMatch(Predicate predicate)
— егер ағынның кем дегенде бір элементі шартты қанағаттандырса, true мәнін қайтарадыpredicate
:Stream.of(1, 2, 3, 4, 9).anyMatch(x -> x >= 7);//true
-
noneMatch(Predicate predicate)
— егер ағынның барлық элементтерінен өтіп, олардың ешқайсысы шартты қанағаттандырмаса, true мәнін қайтарадыpredicate
:Stream.of(1, 2, 3, 4, 9).noneMatch(x -> x >= 7);//false
Collectors
:
-
toList()
— элементтерді жинайдыList
:List<Integer> list = Stream.of(99, 2, 3).collect(Collectors.toList());
-
toSet()
— элементтерді жиынға жинайды:Set<Integer> set = Stream.of(99, 2, 3).collect(Collectors.toSet());
-
counting()
— Элементтердің санын есептейді:Long count = Stream.of("1", "2", "3", "4").collect(Collectors.counting());
-
joining()
-
joining(CharSequence delimiter)
-
joining(CharSequence delimiter, CharSequence prefix, CharSequence suffix)
— элементтерді бір жолға жинайды. Сонымен қатар, сіз бөлгішті, сондай-ақ бүкіл реттілік үшін префикс пен жұрнақты көрсете аласыз:String a = Stream.of("s", "u" ,"p", "e", "r").collect(Collectors.joining()); System.out.println(a); // super String b = Stream.of("s", "u", "p", "e", "r").collect(Collectors.joining("-")); System.out.println(b); // s-u-p-e-r String c = Stream.of("s", "u", "p", "e", "r").collect(Collectors.joining(" -> ", "[ ", " ]")); System.out.println(c); // [ s -> u -> p -> e -> r ]
-
summingInt(ToIntFunction mapper)
-
summingLong(ToLongFunction mapper)
-
summingDouble(ToDoubleFunction mapper)
- an objectілерді int/long/double түрлендіретін және қосындыны есептейтін коллектор.
GO TO FULL VERSION