Java Streams API
A stream (Java 8) is a pipeline to process a collection of data in a clear way: take data, filter it, change it and collect the result. It does not change the original list.
The idea
- Source: a list, an array, or numbers:
list.stream(). - Intermediate steps:
filter,map,sorted,distinct,limit. They are lazy: nothing runs until the end step. - Terminal step:
collect,forEach,count,sum,reduce. This starts the work.
First example
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Integer> numbers = List.of(5, 12, 8, 3, 20, 15, 10);
List<Integer> result = numbers.stream()
.filter(n -> n > 7) // keep big numbers
.map(n -> n * 2) // double them
.sorted()
.toList(); // Java 16+
System.out.println(result);
System.out.println(numbers); // the original is not changed
}
}
[16, 20, 24, 30, 40]
[5, 12, 8, 3, 20, 15, 10]
Common operations
import java.util.List;
public class Ops {
public static void main(String[] args) {
List<String> names = List.of("riya", "aman", "meera", "karan", "aman", "al");
System.out.println(names.stream().distinct().count());
System.out.println(names.stream().filter(n -> n.length() > 3).toList());
System.out.println(names.stream().map(String::toUpperCase).limit(3).toList());
System.out.println(names.stream().sorted().skip(1).findFirst().get());
System.out.println(names.stream().anyMatch(n -> n.startsWith("m")));
System.out.println(names.stream().allMatch(n -> n.length() > 2));
System.out.println(names.stream().mapToInt(String::length).sum());
System.out.println(names.stream().mapToInt(String::length).average().getAsDouble());
}
}
5
[riya, aman, meera, karan, aman]
[RIYA, AMAN, MEERA]
aman
true
false
24
4.0
Collect and reduce
import java.util.List;
import java.util.stream.Collectors;
public class Collect {
public static void main(String[] args) {
List<String> words = List.of("java", "stream", "api", "lambda");
String joined = words.stream().collect(Collectors.joining(", ", "[", "]"));
System.out.println(joined);
int total = List.of(1, 2, 3, 4).stream().reduce(0, Integer::sum);
System.out.println(total);
System.out.println(words.stream().max(java.util.Comparator.comparing(String::length)).get());
}
}
[java, stream, api, lambda]
10
stream
Group the data
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.stream.Collectors;
record Student(String name, String city, int marks) { }
public class Group {
public static void main(String[] args) {
List<Student> students = List.of(
new Student("Riya", "Delhi", 88),
new Student("Aman", "Pune", 72),
new Student("Meera", "Delhi", 95),
new Student("Karan", "Pune", 60));
Map<String, List<String>> byCity = students.stream()
.collect(Collectors.groupingBy(Student::city, TreeMap::new,
Collectors.mapping(Student::name, Collectors.toList())));
System.out.println(byCity);
Map<String, Double> avg = students.stream()
.collect(Collectors.groupingBy(Student::city, TreeMap::new, Collectors.averagingInt(Student::marks)));
System.out.println(avg);
System.out.println(students.stream().filter(s -> s.marks() >= 80).map(Student::name).toList());
}
}
{Delhi=[Riya, Meera], Pune=[Aman, Karan]}
{Delhi=91.5, Pune=66.0}
[Riya, Meera]
Streams of numbers
import java.util.stream.IntStream;
public class Range {
public static void main(String[] args) {
System.out.println(IntStream.rangeClosed(1, 5).sum());
System.out.println(IntStream.range(0, 5).boxed().toList());
System.out.println(IntStream.rangeClosed(1, 20).filter(n -> n % 3 == 0).boxed().toList());
}
}
15
[0, 1, 2, 3, 4]
[3, 6, 9, 12, 15, 18]
A stream can be used only once
import java.util.List;
import java.util.stream.Stream;
public class Once {
public static void main(String[] args) {
Stream<String> s = List.of("a", "b").stream();
System.out.println(s.count());
System.out.println(s.count());
}
}
2
Exception in thread "main" java.lang.IllegalStateException: stream has already been operated upon or closed
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:260)
at java.base/java.util.stream.ReferencePipeline.count(ReferencePipeline.java:750)
at Once.main(Once.java:8)
Rules
- Streams do not store data and do not change the source.
- Do not change outside variables inside a stream (side effects).
- Use
parallelStream()only for big data and heavy work, and measure first.
| Exercises & Assignments |
|---|
| No Content Found. |
| Interview Questions & Answers |
|---|
| No Content Found. |