Terminal Operations: collect(), reduce(), forEach(), match(), and find
Terminal Operations in Java Stream: collect(), reduce(), forEach(), match(), and find
Introduction of Terminal Operations
जब हम Java Stream API का use करते हैं, तो Stream को process करने के बाद हमें किसी result की जरूरत होती है — यही काम करते हैं Terminal Operations। ये operations stream को end करते हैं और final output देते हैं जैसे — list, sum, boolean result या single element। Stream में दो type के operations होते हैं — Intermediate और Terminal, लेकिन याद रखो कि Terminal operation के बाद stream reuse नहीं हो सकती।
मुख्य बात:
- Terminal operation हमेशा final result return करते हैं।
- Stream का life cycle यहीं पर खत्म होता है।
- इनका result या तो single value, boolean, या collection हो सकता है।
अब चलिए step-by-step समझते हैं पाँच सबसे important terminal operations — collect(), reduce(), forEach(), match() और find()।
collect() Operation in Stream
collect() method का use stream elements को किसी collection जैसे List, Set, या Map में convert करने के लिए किया जाता है।
यह सबसे commonly used terminal operation है क्योंकि ये processed data को actual form में store करने में मदद करता है।
Syntax:
List list = stream.collect(Collectors.toList());
Example:
List names = Stream.of("Ram", "Shyam", "Mohan")
.collect(Collectors.toList());
System.out.println(names); // Output: [Ram, Shyam, Mohan]
Use Cases:
- Filter करके results को list या set में store करना।
- Data को grouping या partitioning करना।
- Stream data को easily iterate करने योग्य बनाना।
Common Collectors Methods:
| Collector Method | Description |
|---|---|
| Collectors.toList() | Stream को List में convert करता है। |
| Collectors.toSet() | Stream को Set में convert करता है। |
| Collectors.toMap() | Stream elements को Map के रूप में store करता है। |
| Collectors.joining() | String values को एक single string में जोड़ता है। |
reduce() Operation in Stream
reduce() method का use stream elements को combine करके single result value बनाने के लिए होता है। यह operation functional programming concept — reduction — पर आधारित है। उदाहरण के लिए, sum निकालना, product बनाना या string को join करना।
Syntax:
Optional result = stream.reduce(BinaryOperator);
Example:
List numbers = Arrays.asList(10, 20, 30, 40);
int sum = numbers.stream().reduce(0, (a, b) -> a + b);
System.out.println(sum); // Output: 100
Explanation:
यहाँ reduce() method हर element को पिछले result से जोड़ता जाता है और अंत में single sum देता है।
अगर identity value (जैसे 0 या "") दी गई है, तो process उसी से शुरू होता है।
Use Cases:
- Sum, average, multiplication जैसे aggregate calculations के लिए।
- String concatenation के लिए।
- Custom computation या object combine करने के लिए।
forEach() Operation in Stream
forEach() एक simple और powerful terminal operation है जो stream के हर element पर एक action perform करता है। यह कुछ return नहीं करता — बस elements को process या print करता है।
Syntax:
stream.forEach(action);
Example:
List names = Arrays.asList("Aman", "Ravi", "Priya");
names.stream().forEach(n -> System.out.println(n));
Output:
Aman
Ravi
Priya
Use Cases:
- Stream elements को print करने के लिए।
- Logging, debugging या external operations के लिए।
- Non-returning side effects के लिए।
Important Note:
forEach() के अंदर mutable objects को modify करने से बचना चाहिए, क्योंकि ये parallel streams में unpredictable behavior पैदा कर सकता है।
match() Operations in Stream
match() methods boolean result return करते हैं। इनका use यह check करने के लिए होता है कि stream elements किसी condition को satisfy करते हैं या नहीं।
Types of match operations:
| Method | Return Type | Description |
|---|---|---|
| anyMatch(Predicate) | boolean | अगर कोई भी element condition match करता है, तो true return करता है। |
| allMatch(Predicate) | boolean | अगर सभी elements condition satisfy करते हैं, तो true return करता है। |
| noneMatch(Predicate) | boolean | अगर कोई भी element condition satisfy नहीं करता, तो true return करता है। |
Example:
List nums = Arrays.asList(2, 4, 6, 8, 10);
boolean allEven = nums.stream().allMatch(n -> n % 2 == 0);
System.out.println(allEven); // Output: true
Explanation:
यहाँ allMatch() check करता है कि क्या सभी numbers even हैं। क्योंकि सारे elements even हैं, इसलिए output true आया।
Use Cases:
- Data validation करने के लिए।
- Condition checking जैसे student marks >= 40 हैं या नहीं।
- Filtering से पहले pre-check करने के लिए।
find() Operations in Stream
findFirst() और findAny() methods का use stream से element निकालने के लिए किया जाता है। ये Optional return करते हैं ताकि null pointer issues न हों।
Syntax:
OptionalfindFirst() OptionalfindAny()
Example:
List names = Arrays.asList("Ramesh", "Suresh", "Mahesh", "Dinesh");
Optional firstName = names.stream().findFirst();
System.out.println(firstName.get()); // Output: Ramesh
Explanation:
findFirst() हमेशा first element return करता है (Stream के order के हिसाब से)। जबकि findAny() parallel stream में किसी भी element को return कर सकता है।
Use Cases:
- Stream से पहला या कोई एक element निकालने के लिए।
- Quick lookup operations के लिए।
- Optional handling के साथ safe retrieval के लिए।
Difference Between collect(), reduce(), forEach(), match(), and find()
| Operation | Return Type | Main Use | Example |
|---|---|---|---|
| collect() | Collection (List, Set, Map) | Stream को collection में convert करना | collect(Collectors.toList()) |
| reduce() | Single value (Optional) | Aggregation जैसे sum या concatenation | reduce(0, (a,b)->a+b) |
| forEach() | void | हर element पर action perform करना | forEach(System.out::println) |
| match() | boolean | Condition check करना | allMatch(n->n>0) |
| find() | Optional | Stream से element प्राप्त करना | findFirst() |
Key Points to Remember
- Terminal operations stream को close कर देते हैं।
- Intermediate operations lazy होते हैं, लेकिन terminal operations eager होते हैं।
- forEach() side-effect operations के लिए use होता है।
- reduce() aggregation के लिए perfect है।
- collect() data को collection में बदलने के लिए सबसे useful है।
- match() और find() mostly searching और checking के लिए use होते हैं।
Practical Example: Combining Multiple Terminal Operations
List students = Arrays.asList("Aman", "Ravi", "Priya", "Riya", "Ajay");
boolean result = students.stream()
.filter(s -> s.startsWith("A"))
.collect(Collectors.toList())
.stream()
.allMatch(name -> name.length() > 2);
System.out.println(result); // Output: true
यहाँ हमने filter(), collect(), और match() तीन operations को एक साथ use किया है। इससे ये साबित होता है कि Terminal operations को समझना Stream API में mastery पाने के लिए बहुत जरूरी है।
Exam-Oriented Notes
- collect(): Stream elements को List, Set, या Map में collect करता है।
- reduce(): Elements को combine करके single result देता है।
- forEach(): हर element पर action perform करता है (return कुछ नहीं)।
- match(): Boolean return करता है — condition check करता है।
- find(): Optional return करता है — first या any element देता है।
- Stream को reuse नहीं किया जा सकता अगर उस पर terminal operation लग चुका है।
- Optional class null handling में help करती है।
- collect() और reduce() data aggregation के लिए सबसे useful हैं।