Java 8-де Java Threads-ке кіріспе
Java 8 бөлігі ретінде енгізілген Java Streams деректер жинақтарымен жұмыс істеу үшін пайдаланылады. Олардың өзі деректер құрылымы емес, бірақ түпкілікті нәтиже шығару үшін тапсырыс беру және конвейерлеу арқылы басқа деректер құрылымдарынан ақпаратты енгізу үшін пайдаланылуы мүмкін. Ескертпе: Ағын мен ағынды шатастырмау маңызды, өйткені орыс тілінде екі термин де бір аудармада «ағын» деп аталады. Stream операцияларды орындауға арналған an objectіні (көбінесе деректерді тасымалдау немесе сақтау) білдіреді, ал Thread (сөзбе-сөз аударма - ағын) белгілі бір бағдарлама codeын басқа code тармақтарымен параллель орындауға мүмкіндік беретін an objectіні білдіреді. Stream жеке деректер құрылымы болмағандықтан, ол деректер көзін ешқашан өзгертпейді. Java ағындарының келесі мүмкіндіктері бар:-
Java ағынын «java.util.stream» бумасы арқылы пайдалануға болады. Оны codeты пайдаланып сценарийге импорттауға болады:
import java.util.stream.* ;
Осы codeты пайдалана отырып, біз Java Stream жүйесінде бірнеше кірістірілген функцияларды оңай іске асыра аламыз.
-
Java ағыны Java тіліндегі жинақтар мен массивтер сияқты деректер жинақтарынан енгізуді қабылдай алады.
-
Java Stream кіріс деректер құрылымын өзгертуді қажет етпейді.
-
Java Stream көзді өзгертпейді. Оның орнына ол сәйкес құбыр жолдарының әдістерін пайдалана отырып, өнім шығарады.
-
Java ағындары аралық және терминалдық операцияларға жатады, біз оларды келесі бөлімдерде қарастырамыз.
-
Java ағынында аралық операциялар конвейерленген және жалқау бағалау пішімінде орын алады. Олар терминалдық функциялармен аяқталады. Бұл Java Stream пайдаланудың негізгі пішімін құрайды.
Java 8-де Java Stream құру
Java ағындарын бірнеше жолмен жасауға болады:1. Stream.empty() әдісі арқылы бос ағын жасау
Кодыңызда кейінірек пайдалану үшін бос ағын жасай аласыз. Stream.empty() әдісін пайдалансаңыз , мәндері жоқ бос ағын жасалады. Бұл бос ағын орындалу уақытында нөлдік көрсеткішті өткізіп жібергіміз келсе, пайдалы болуы мүмкін. Мұны істеу үшін келесі пәрменді пайдалануға болады:Stream<String> str = Stream.empty();
Жоғарыдағы мәлімдеме ішінде ешқандай элементтері жоқ str деп аталатын бос ағын жасайды . Мұны тексеру үшін str.count() терминін пайдаланып ағынның санын немесе өлшемін тексеріңіз . Мысалы,
System.out.println(str.count());
Нәтижесінде біз шығысында 0 аламыз .
2. Stream.Builder данасы арқылы Stream.builder() әдісін пайдаланып ағын жасаңыз.
Сондай-ақ біз Stream Builder бағдарламасын құрастырушы дизайн үлгісін пайдаланып ағын жасау үшін пайдалана аламыз . Ол an objectілерді кезең-кезеңімен салуға арналған. Stream Builder көмегімен ағынды қалай жасауға болатынын көрейік .Stream.Builder<Integer> numBuilder = Stream.builder();
numBuilder.add(1).add(2).add( 3);
Stream<Integer> numStream = numBuilder.build();
Бұл codeты пайдаланып, құрамында int элементтері бар numStream атты ағын жасауға болады . Алдымен жасалған numBuilder деп аталатын Stream.Builder данасы арқасында бәрі тез орындалады .
3. Stream.of() әдісін пайдаланып көрсетілген мәндері бар ағын жасаңыз
Ағын жасаудың тағы бір жолы Stream.of() әдісін пайдалануды қамтиды . Бұл берілген мәндері бар ағын жасаудың қарапайым жолы. Ол ағынды жариялайды және инициализациялайды. Ағын жасау үшін Stream.of() әдісін пайдалану мысалы:Stream<Integer> numStream = Stream.of(1, 2, 3);
Бұл code Stream.Builder арқылы алдыңғы әдісте жасағандай, int элементтері бар ағынды жасайды . Мұнда біз Stream.of() арқылы алдын ала анықталған мәндері бар [1, 2 және 3] ағынын тікелей жасадық .
4. Arrays.stream() әдісін пайдаланып бар массивтен ағын жасаңыз
Жіпті құрудың тағы бір кең таралған әдісі Java-да массивтерді пайдалануды қамтиды. Мұндағы ағын Arrays.stream() әдісі арқылы бар массивтен жасалған . Барлық массив элементтері ағындық элементтерге түрлендіріледі. Міне жақсы мысал:Integer[] arr = {1, 2, 3, 4, 5};
Stream<Integer> numStream = Arrays.stream(arr);
Бұл code бүтін массив болып табылатын arr деп аталатын массивтің мазмұнын қамтитын numStream жасайды .
5. Stream.concat() әдісі арқылы бар екі ағынды біріктіру
Ағынды жасаудың тағы бір әдісі Stream.concat() әдісі болып табылады . Ол бір жіп жасау үшін екі ағынды біріктіру үшін қолданылады. Екі ағын да ретімен біріктірілген. Бұл бірінші жіптің бірінші, одан кейін екінші жіптің және т.б. Мұндай біріктірудің мысалы келесідей:Stream<Integer> numStream1 = Stream.of(1, 2, 3, 4, 5);
Stream<Integer> numStream2 = Stream.of(1, 2, 3);
Stream<Integer> combinedStream = Stream.concat( numStream1, numStream2);
Жоғарыдағы мәлімдеме бірінші ағынның numStream1 және екінші ағынының numStream2 элементтерін бір-бірден қамтитын combinedStream деп аталатын соңғы ағынды жасайды .
Java Stream көмегімен операциялар түрлері
Жоғарыда айтылғандай, Java 8-де Java Stream көмегімен екі операция түрін орындауға болады: аралық және терминал. Олардың әрқайсысын толығырақ қарастырайық.Аралық операциялар
Аралық операциялар шығыс ағынын жасайды және терминал операциясымен кездескен кезде ғана орындалады. Бұл аралық операциялардың жалқаулықпен орындалатынын, конвейерленгенін және тек терминалдық операция арқылы аяқталатынын білдіреді. Жалқау бағалау және конвейерлеу туралы сәл кейінірек білесіз. Аралық операциялардың мысалдары келесі әдістер: filter() , map() , different() , peek() , sorted() және басқалары.Терминал операциялары
Терминал операциялары аралық операциялардың орындалуын аяқтайды, сонымен қатар шығыс ағынының соңғы нәтижелерін қайтарады. Терминал операциялары жалқау орындалу мен конвейерлеудің аяқталуын білдіретіндіктен, бұл ағынды терминал операциясынан өткеннен кейін қайта пайдалану мүмкін емес. Терминал операцияларының мысалдары келесі әдістер болып табылады: forEach() , collect() , count() , reduce() және т.б.Java Stream көмегімен операциялардың мысалдары
Аралық операциялар
Мұнда Java ағынына қолдануға болатын кейбір аралық операциялардың мысалдары берілген:сүзгі()
Бұл әдіс Java тіліндегі белгілі бір предикатқа сәйкес келетін ағынның элементтерін сүзу үшін қолданылады. Бұл сүзгіден өткен элементтер жаңа ағынды құрайды. Жақсырақ түсіну үшін мысалды қарастырайық.Stream<Integer> numStream = Stream.of(43, 65, 1, 98, 63); List<Integer> even = numStream.filter(n -> n % 2 == 0) .collect(Collectors.toList()); System.out.println(even);
Қорытынды:
карта()
Бұл әдіс бастапқы кіріс ағынының элементтерінде салыстырылған функцияларды орындау арқылы жаңа ағын жасау үшін пайдаланылады. Жаңа ағынның басқа деректер түрі болуы мүмкін. Мысал келесідей көрінеді:Stream<Integer> numStream = Stream.of(43, 65, 1, 98, 63); List<Integer> d = numStream.map(n -> n*2) .collect(Collectors.toList()); System.out.println(d);
Қорытынды:
бөлек()
Бұл әдіс көшірмелерді сүзу арқылы ағындағы жеке элементтерді ғана алу үшін пайдаланылады. Бірдей мысал келесідей көрінеді:Stream<Integer> numStream = Stream.of(43,65,1,98,63,63,1); List<Integer> numList = numStream.distinct() .collect(Collectors.toList()); System.out.println(numList);
Қорытынды:
қарау()
Бұл әдіс терминал операциясын орындамас бұрын аралық өзгерістерді бақылау үшін қолданылады. Бұл әрі қарай аралық операцияларды орындауға болатын ағын жасау үшін ағынның әрбір элементінде әрекетті орындау үшін peek() функциясын пайдалануға болатынын білдіреді .Stream<Integer> numStream = Stream.of(43, 65, 1, 98, 63); List<Integer> nList = numStream.map(n -> n*10) .peek(n->System.out.println("Mapped: "+ n)) .collect(Collectors.toList()); System.out.println(nList);
Қорытынды:
сұрыпталған()
Ағынның элементтерін сұрыптау үшін sorted() әдісі қолданылады. Әдепкі бойынша ол элементтерді өсу ретімен сұрыптайды. Сондай-ақ, параметр ретінде арнайы сұрыптау ретін көрсетуге болады. Бұл әдісті іске асырудың мысалы келесідей көрінеді:Stream<Integer> numStream = Stream.of(43, 65, 1, 98, 63); numStream.sorted().forEach(n -> System.out.println(n));
Қорытынды:
Терминал операциялары
Мұнда Java ағындарына қолдануға болатын кейбір терминалдық әрекеттердің мысалдары берілген:әрқайсысы үшін()
ForEach() әдісі ағынның барлық элементтерін қайталау және функцияны әрбір элементте бір-бірден орындау үшін қолданылады. Бұл for , while және басқалары сияқты цикл операторларына балама ретінде әрекет етеді . Мысалы:Stream<Integer> numStream = Stream.of(43, 65, 1, 98, 63); numStream.forEach(n -> System.out.println(n));
Қорытынды:
санау()
count() әдісі ағында бар элементтердің жалпы санын шығару үшін пайдаланылады. Ол коллекциядағы элементтердің жалпы санын анықтау үшін жиі қолданылатын size() әдісіне ұқсас . Java ағынымен count() әдісін пайдалану мысалы төмендегідей:Stream<Integer> numStream = Stream.of(43, 65, 1, 98, 63); System.out.println(numStream.count());
Қорытынды:
жинау()
Collection() әдісі ағын элементтерінің өзгермелі қысқартуларын орындау үшін қолданылады. Оны өңдеу аяқталғаннан кейін ағыннан мазмұнды жою үшін пайдалануға болады. Ол қысқартуларды орындау үшін Коллектор класын пайдаланады .Stream<Integer> numStream = Stream.of(43, 65, 1, 98, 63); List<Integer> odd = numStream.filter(n -> n % 2 == 1) .collect(Collectors.toList()); System.out.println(odd);
Қорытынды:
min() және max()
min() әдісі , аты айтып тұрғандай, ағындағы ең аз элементті табу үшін пайдаланылуы мүмкін. Сол сияқты max() әдісін ағындағы максималды элементті табу үшін пайдалануға болады. Оларды мысалмен қалай қолдануға болатынын түсінуге тырысайық:Stream<Integer> numStream = Stream.of(43, 65, 1, 98, 63); int smallest = numStream.min((m, n) -> Integer.compare(m, n)).get(); System.out.println("Smallest element: " + smallest);
numStream = Stream.of(43, 65, 1, 98, 63); int largest = numStream.max((m, n) -> Integer.compare(m, n)).get(); System.out.println("Largest element: " + largest);
Қорытынды:
findAny() және findFirst()
findAny() ағынның кез келген элементін Қосымша ретінде қайтарады . Егер ағын бос болса, ол бос болатын Қосымша мәнді де қайтарады . findFirst() ағынның бірінші элементін Қосымша ретінде қайтарады . findAny() әдісі сияқты , findFirst() әдісі де сәйкес ағын бос болса, бос Қосымша параметрді қайтарады . Осы әдістерге негізделген келесі мысалды қарастырайық:Stream<Integer> numStream = Stream.of(43, 65, 1, 98, 63); Optional<Integer> opt = numStream.findFirst();System.out.println(opt); numStream = Stream.empty(); opt = numStream.findAny();System.out.println(opt);
Қорытынды:
allMatch() , anyMatch() және noneMatch()
allMatch() әдісі ағындағы барлық элементтердің белгілі бір предикатқа сәйкестігін тексеру үшін пайдаланылады және егер сәйкес келсе, логикалық мәнді true қайтарады, әйтпесе false мәнін қайтарады . Егер ағын бос болса, ол true мәнін қайтарады . anyMatch() әдісі ағындағы элементтердің кез келгенінің белгілі бір предикатқа сәйкес келетінін тексеру үшін қолданылады. Ол солай болса, шын мәнін , әйтпесе жалған мәнін қайтарады . Егер ағын бос болса, ол false мәнін қайтарады . noneMatch() әдісі егер ағындағы ешбір элемент предикатқа сәйкес келмесе, true мәнін қайтарады , ал басқаша жағдайда false мәнін қайтарады . Мұны көрсету үшін мысал келесідей көрінеді:Stream<Integer> numStream = Stream.of(43, 65, 1, 98, 63); boolean flag = numStream.allMatch(n -> n1); System.out.println(flag); numStream = Stream.of(43, 65, 1, 98, 63); flag = numStream.anyMatch(n -> n1); System.out.println(flag); numStream = Stream.of(43, 65, 1, 98, 63); flag = numStream.noneMatch(n -> n==1);System.out.println(flag);
Қорытынды:
Java ағынындағы жалқау бағалаулар
Жалқау бағалау Java 8 жүйесінде Java ағындарымен жұмыс істеу кезінде оңтайландыруларға әкеледі. Олар негізінен терминал операциясы кездескенше аралық операцияларды кейінге қалдыруды қамтиды. Жалқау бағалау нәтиже нақты қажет болғанға дейін есептеулерде ресурстарды қажетсіз ысырап етудің алдын алуға жауап береді. Аралық операциялардың нәтижесінде пайда болатын шығыс ағыны терминал жұмысы аяқталғаннан кейін ғана жасалады. Жалқау бағалау Java ағындарындағы барлық аралық операциялармен жұмыс істейді. Жалқау бағалаудың өте пайдалы қолданылуы шексіз ағындармен жұмыс істегенде орын алады. Осылайша, көптеген қажетсіз өңдеудің алдын алады.Java ағынындағы құбырлар
Java ағынындағы құбыр желісі кіріс ағынынан, бірінен соң бірі реттелген нөлдік немесе одан да көп аралық операциялардан және соңында терминал операциясынан тұрады. Java ағындарында аралық операциялар жалқау орындалады. Бұл құбырлы аралық операцияларды сөзсіз етеді. Негізінен ретімен біріктірілген аралық операциялар болып табылатын құбыр желілерімен жалқау орындау мүмкін болады. Құбырлар терминал операциясы ақырында кездескеннен кейін орындалуы қажет аралық операцияларды қадағалауға көмектеседі.Қорытынды
Енді бүгін алған білімімізді қорытындылайық. Бұл мақалада:- Біз Java ағындарының не екенін жылдам қарастырдық.
- Содан кейін біз Java 8-де Java ағындарын жасаудың көптеген әртүрлі әдістерін үйрендік.
- Біз Java ағындарында орындалатын операциялардың екі негізгі түрін (аралық операциялар және терминалдық операциялар) үйрендік.
- Содан кейін біз аралық және терминалдық операциялардың бірнеше мысалдарын егжей-тегжейлі қарастырдық.
- Біз жалқау бағалау туралы көбірек білдік және соңында Java ағындарында конвейер құру туралы білдік.
GO TO FULL VERSION