זרם הוצג ב Java 8 ה- Stream API משמש לעיבוד אוספים של אובייקטים. זרם ב-Java הוא רצף של אובייקטים התומך בשיטות שונות שניתן לבצע בצינור כדי להפיק את התוצאה הרצויה.
שימוש ב-Stream ב-Java
השימושים של Stream ב-Java מוזכרים להלן:
- Stream API היא דרך לבטא ולעבד אוספים של אובייקטים.
- אפשרו לנו לבצע פעולות כמו סינון מיפוי צמצום ומיון.
כיצד ליצור זרם Java
יצירת זרם Java היא אחד השלבים הבסיסיים ביותר לפני ששוקלים את הפונקציונליות של זרם Java. להלן התחביר שניתן להכרזה על זרם Java.
java לעשות בזמן
תַחבִּיר
זֶרֶם
זֶרֶם;
כאן T הוא אובייקט מחלקה או סוג נתונים בהתאם להצהרה.
תכונות זרם Java
התכונות של זרמי Java מוזכרות להלן:
- זרם אינו מבנה נתונים; זה רק לוקח קלט מערכי קולקציות או ערוצי קלט/פלט.
- זרמים אינם משנים את הנתונים המקוריים; הם מייצרים תוצאות רק באמצעות השיטות שלהם.
- פעולות ביניים (כמו מפת סינון וכו') עצלניות ומחזירות עוד זרם כדי שתוכלו לשרשר אותן יחד.
- פעולת טרמינל (כמו collect forEach count) מסיימת את הזרם ונותנת את התוצאה הסופית.
פעולות שונות בזרמים
ישנם שני סוגים של פעולות בזרמים:
- פעולות ביניים
- תפעול מסוף
פעולות ביניים

פעולות ביניים הן סוגי הפעולות שבהן משורשרות שיטות מרובות ברצף.
מאפיינים של פעולות ביניים
- שיטות משורשרות יחד.
- פעולות ביניים הופכות זרם לזרם אחר.
- זה מאפשר את הרעיון של סינון שבו שיטה אחת מסננת נתונים ומעבירה אותם לשיטה אחרת לאחר עיבוד.
פעולות ביניים חשובות
להלן מספר פעולות ביניים:
1. map() : שיטת המפה משמשת להחזרת זרם המורכב מתוצאות החלת הפונקציה הנתונה על האלמנטים של זרם זה.
תַחבִּיר:
זֶרֶם מפה (פונקציה super T ? extends R>ממפה)
2. מסנן() : שיטת הסינון משמשת לבחירת אלמנטים לפי הפרדיקט המועבר כארגומנט.
תַחבִּיר:
זֶרֶם
מסנן (פרדיקט super T>לְבַסֵס)
3. sorted() : השיטה הממוינת משמשת למיון הזרם.
תַחבִּיר:
זֶרֶם
מְמוּיָן()
זֶרֶםsorted(Comparator super T>משווה)
4. flatMap(): פעולת flatMap ב-Java Streams משמשת כדי לשטח זרם של אוספים לזרם יחיד של אלמנטים.
תַחבִּיר:
זֶרֶם flatMap(פונקציה super T ? extends Stream extends R>> ממפה)
5. distinct() : מסיר רכיבים כפולים. הוא מחזיר זרם המורכב מהאלמנטים הנבדלים (לפי Object.equals(Object)).
תַחבִּיר:
זֶרֶם
מוּבהָק()
6. הצצה() : מבצע פעולה בכל רכיב מבלי לשנות את הזרם. הוא מחזיר זרם המורכב מהאלמנטים של הזרם הזה ובנוסף מבצע את הפעולה שסופקה על כל אלמנט כאשר אלמנטים נצרכים מהזרם שנוצר.
תַחבִּיר:
זֶרֶם
הצצה (צרכן super T>פְּעוּלָה)
תוכנת Java המדגימה את השימוש בכל פעולות הביניים:
שיטת java tostringJava
import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.stream.Collectors; public class StreamIntermediateOperationsExample { public static void main(String[] args) { // List of lists of names List<List<String>> listOfLists = Arrays.asList( Arrays.asList('Reflection' 'Collection' 'Stream') Arrays.asList('Structure' 'State' 'Flow') Arrays.asList('Sorting' 'Mapping' 'Reduction' 'Stream') ); // Create a set to hold intermediate results Set<String> intermediateResults = new HashSet<>(); // Stream pipeline demonstrating various intermediate operations List<String> result = listOfLists.stream() .flatMap(List::stream) .filter(s -> s.startsWith('S')) .map(String::toUpperCase) .distinct() .sorted() .peek(s -> intermediateResults.add(s)) .collect(Collectors.toList()); // Print the intermediate results System.out.println('Intermediate Results:'); intermediateResults.forEach(System.out::println); // Print the final result System.out.println('Final Result:'); result.forEach(System.out::println); } }
תְפוּקָה
Intermediate Results: STRUCTURE STREAM STATE SORTING Final Result: SORTING STATE STREAM STRUCTURE
הֶסבֵּר:
- ה-listOfLists נוצר כרשימה המכילה רשימות אחרות של מחרוזות.
- flatMap(List::stream): משטח את הרשימות המקוננות לזרם יחיד של מחרוזות.
- מסנן(ים -> s.startsWith('S')) : מסנן את המחרוזות כך שיכלול רק את אלה שמתחילות ב-'S'.
- map(String::toUpperCase) : ממירה כל מחרוזת בזרם לאותיות רישיות.
- מוּבהָק() : מסיר מחרוזות כפולות.
- מְמוּיָן() : ממיין את המחרוזות המתקבלות בסדר אלפביתי.
- לְהָצִיץ(...): מוסיף כל רכיב מעובד לקבוצת הבינייםResults לבדיקת ביניים.
- collect(Collectors.toList()): אוסף את המחרוזות המעובדות הסופיות לרשימה שנקראת תוצאה.
התוכנית מדפיסה את תוצאות הביניים המאוחסנות בערכת תוצאות הביניים. לבסוף הוא מדפיס את רשימת התוצאות המכילה את המחרוזות המעובדות במלואן לאחר כל פעולות הזרם.
תפעול מסוף
פעולות מסוף הן סוג הפעולות שמחזירות את התוצאה. פעולות אלו אינן מעובדות יותר רק מחזירות ערך תוצאה סופי.
פעולות טרמינל חשובות
1. collect() : שיטת האיסוף משמשת להחזרת התוצאה של פעולות הביניים שבוצעו בזרם.
תַחבִּיר:
R collect(אספן super T A R>אַסְפָן)
2. forEach() : שיטת forEach משמשת לחזרה על כל רכיב בזרם.
תַחבִּיר:
void forEach(Consumer super T>פְּעוּלָה)
3. להפחית(): שיטת ההפחתה משמשת לצמצום הרכיבים של זרם לערך בודד. שיטת ההפחתה לוקחת את BinaryOperator כפרמטר.
תַחבִּיר:
T reduce(T identity BinaryOperator
מַצבֵּר)
אופציונליreduce(BinaryOperator מַצבֵּר)
4. count() : מחזירה את ספירת הרכיבים בזרם.
תַחבִּיר:
ספירה ארוכה()
5. findFirst() : מחזירה את הרכיב הראשון של הזרם אם קיים.
תַחבִּיר:
אופציונלי
findFirst() מיון רשימות מערך
6. allMatch() : בודק אם כל הרכיבים של הזרם תואמים לפרדיקט נתון.
תַחבִּיר:
boolean allMatch(Predicate super T>לְבַסֵס)
7. Anymatch () : בודק אם רכיב כלשהו בזרם תואם לפרדיקט נתון.
תַחבִּיר:
בוליאנית Anymatch (פרדיקט super T>לְבַסֵס)
כאן ans משתנה מוקצה 0 כערך ההתחלתי ו-i מתווסף אליו.
פֶּתֶק: פעולות ביניים פועלות על בסיס הרעיון של Lazy Evaluation אשר מבטיח שכל שיטה מחזירה ערך קבוע (פעולת טרמינל) לפני המעבר לשיטה הבאה.
תוכנית Java המשתמשת בכל פעולות המסוף:
Javaimport java.util.*; import java.util.stream.Collectors; public class StreamTerminalOperationsExample { public static void main(String[] args) { // Sample data List<String> names = Arrays.asList( 'Reflection' 'Collection' 'Stream' 'Structure' 'Sorting' 'State' ); // forEach: Print each name System.out.println('forEach:'); names.stream().forEach(System.out::println); // collect: Collect names starting with 'S' into a list List<String> sNames = names.stream() .filter(name -> name.startsWith('S')) .collect(Collectors.toList()); System.out.println('ncollect (names starting with 'S'):'); sNames.forEach(System.out::println); // reduce: Concatenate all names into a single string String concatenatedNames = names.stream().reduce( '' (partialString element) -> partialString + ' ' + element ); System.out.println('nreduce (concatenated names):'); System.out.println(concatenatedNames.trim()); // count: Count the number of names long count = names.stream().count(); System.out.println('ncount:'); System.out.println(count); // findFirst: Find the first name Optional<String> firstName = names.stream().findFirst(); System.out.println('nfindFirst:'); firstName.ifPresent(System.out::println); // allMatch: Check if all names start with 'S' boolean allStartWithS = names.stream().allMatch( name -> name.startsWith('S') ); System.out.println('nallMatch (all start with 'S'):'); System.out.println(allStartWithS); // anyMatch: Check if any name starts with 'S' boolean anyStartWithS = names.stream().anyMatch( name -> name.startsWith('S') ); System.out.println('nanyMatch (any start with 'S'):'); System.out.println(anyStartWithS); } }
תְפוּקָה:
תְפוּקָההֶסבֵּר:
- רשימת השמות נוצרת עם מחרוזות לדוגמה.
- לכל אחד: מדפיס כל שם ברשימה.
- לֶאֱסוֹף : מסנן שמות שמתחילים ב-'S' ואוסף אותם לרשימה חדשה.
- לְהַפחִית : משרשרת את כל השמות למחרוזת אחת.
- לִסְפּוֹר : סופר את המספר הכולל של שמות.
- מצא ראשון : מוצא ומדפיס את השם הפרטי ברשימה.
- allMatch : בודק אם כל השמות מתחילים ב-'S'.
- בִּישׁ מַזָל : בודק אם שם כלשהו מתחיל ב-'S'.
התוכנית מדפיסה כל שם שמות מתחילים ב-'S' שמות משורשרים את ספירת השמות את השם הפרטי בין אם כל השמות מתחילים ב-'S' והאם שם כלשהו מתחיל ב-'S'.
היתרון של Java Stream
ישנם כמה יתרונות שבגללם אנו משתמשים ב-Stream ב-Java כפי שהוזכר להלן:
- אין אחסון
- צינור של פונקציות
- עַצלוּת
- יכול להיות אינסופי
- ניתן להקביל
- ניתן ליצור ממערכי אוספים שיטות קווים ב-Stream IntStream וכו'.
מקרי שימוש בעולם האמיתי של זרמי Java
זרמים נמצאים בשימוש נרחב ביישומי Java מודרניים עבור:
- עיבוד נתונים
- לעיבוד תגובות JSON/XML
- עבור פעולות מסד נתונים
- עיבוד במקביל