Stream Basics
/**
* STREAMS IN JAVA
* ---------------
* Streams were introduced in Java 8 to process collections
* in a functional and declarative style.
*
* Common operations: filter, map, collect, reduce
*
* Key ideas:
* - A stream is not a data storage (not a collection)
* - It works with pipelines
* - Supports lazy evaluation
* - Encurage declarative programming
*/
package com.minte9.streams.streams_basics;
import java.util.Arrays;
import java.util.List;
public class StreamsBasics {
public static void main(String[] args) {
List<String> names = Arrays.asList("John", "Jane", "Doe", "Julia");
// Traditional way
for (String name : names) {
if (name.startsWith("J")) {
System.out.println(name); // John Jane Julia
}
}
// Stream way
names.stream()
.filter(x -> x.startsWith("J"))
.forEach(System.out::println);
}
}
Common Operations
/**
* STREAMS - MOST COMMON OPERATIONS
* --------------------------------
* Filter:
* - Select elements based on a condition (Predicate)
*
* Mapping:
* - Transform each element into another form
*
* Sorting:
* - Sort elements (natural or custom comparator)
*
* Collecting:
* - Convert stream into a collection or other result
*
* Reduce:
* - Combine elements into a single result
*
*/
package com.minte9.streams.streams_basics;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class CommonOperations {
public static void main(String[] args) {
// Filter
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);
numbers.stream()
.filter(n -> n % 2 == 0)
.forEach(System.out::println); // 2 4 6
// Mapping
List<String> names = Arrays.asList("john", "jane", "jack");
names.stream()
.map(String::toUpperCase)
.forEach(System.out::println); // JOHN JANE JACK
List<Integer> nums = Arrays.asList(1, 2, 3);
int sum = nums.stream()
.mapToInt(Integer::intValue)
.sum();
System.out.println("Sum: " + sum); // 6
// Sorting
List<Integer> items = Arrays.asList(5, 2, 8, 1);
items.stream()
.sorted()
.forEach(System.out::println); // 1 2 5 8
// Collecting
List<String> filtered =
names.stream()
.filter(name -> name.startsWith("j"))
.collect(Collectors.toList());
System.out.println(filtered); // [john, jane, jack]
// Reduce
sum = numbers.stream()
.reduce(0, (a, b) -> a + b);
System.out.println("Sum: " + sum); // 21
}
}
Iteration Styles
/**
* STREAMS - ITERATION STYLES
* --------------------------
* Streams allow us to write collection-processing code
* at a higher level of abstraction.
*
* TWO APPROACHES:
* ---------------
* External iteration (imperative):
* - The developer controls HOW iteration happens
* - Uses loops or iterators
* - Requires mutable state (counter, variables)
*
* Internal iteration (declarative):
* - The library controls HOW iteration hapens
* - The developer specifies WHAT should be done
* - No explicit loops or mutable counters
*
* Iterator - external iterator
* Stream - internal iterator
*/
package com.minte9.streams.streams_basics;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
public class IterationStyles {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3);
int count;
// External iteration (for-each loop)
count = 0;
for (int n : numbers) {
if (n <= 2) {
count++;
}
}
System.out.println(count); // 2
// External iteration (Iterator)
count = 0;
Iterator<Integer> it = numbers.iterator();
while(it.hasNext()) {
int n = it.next();
if (n <= 2) {
count++;
}
}
System.out.println(count); // 2
// Internal iteration - Stream
long total =
numbers.stream()
.filter(n -> n <= 2)
.count();
System.out.println(total); // 2
}
}
Laziness
/**
* STREAMS - LAZY EVALUATION
* -------------------------
* Streams are evaluated lazily.
*
* KEY IDEAS:
* ----------
* - A stream does NOT process data when it is created
* - Intermediate operations (filter, map) are lazy
* - Nothing happens until a TERMINAL operation is invoked
*
* TERMINAL OPERATIONS:
* --------------------
* - count()
* - forEach()
* - collect()
* - findFirst()
* - anyMatch()
*
* Without a terminal operation, a stream does nothing.
*
* When we write numbers.strea().filter(...) we are only
* describing a pipeline.
*/
package com.minte9.streams.streams_basics;
import java.util.Arrays;
import java.util.List;
public class Laziness {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3);
// No terminal operation - nothing happens (no output)
numbers.stream()
.filter(n -> {
System.out.println("filter: " + n);
return n <= 2;
});
// Terminal operation triggers evaluation
numbers.stream()
.filter(n -> {
System.out.println("filter: " + n);
return n <= 2;
})
.count(); // Output: 1 2 3
}
}