0% found this document useful (0 votes)
14 views4 pages

Java Streams Tutorial Complete

The document provides an overview of Java Streams, detailing their characteristics, creation methods, and operations such as intermediate and terminal operations. It includes examples of using streams for various tasks, including filtering, mapping, reducing, and collecting data, as well as handling files and exceptions. Additionally, it offers performance tips, common patterns, and mini project ideas for practice.

Uploaded by

Abhay Tiwari
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
14 views4 pages

Java Streams Tutorial Complete

The document provides an overview of Java Streams, detailing their characteristics, creation methods, and operations such as intermediate and terminal operations. It includes examples of using streams for various tasks, including filtering, mapping, reducing, and collecting data, as well as handling files and exceptions. Additionally, it offers performance tips, common patterns, and mini project ideas for practice.

Uploaded by

Abhay Tiwari
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 4

1) What is a Stream?

- A Stream is a sequence of elements supporting functional-style operations (map, filter, reduce


- It is not a data structure; it doesn’t store elements.
- It’s lazy: intermediate operations don’t run until a terminal operation triggers evaluation.
- It’s once-use: a stream can be consumed only once.

Example:
List<Integer> nums = List.of(1,2,3,4,5);
int sum2 = nums.stream()
.filter(n -> n % 2 == 0)
.map(n -> n * n)
.reduce(0, Integer::sum);

2) Creating Streams
Stream<String> s1 = List.of("a","b","c").stream();
IntStream s2 = Arrays.stream(new int[]{1,2,3});
Stream<String> s3 = Stream.of("x","y","z");
Stream<Double> randoms = Stream.generate(Math::random).limit(5);
IntStream range = IntStream.range(0, 10);

3) Intermediate Operations (lazy)


filter, map, flatMap, distinct, sorted, peek, limit, skip
Example:
List<String> result = names.stream()
.filter(n -> n.length() <= 3)
.map(String::toUpperCase)
.distinct()
.sorted()
.toList();

4) Terminal Operations
forEach, collect, reduce, min, max, count, anyMatch, allMatch, findFirst
Example:
Optional<String> longest =
names.stream().max(Comparator.comparingInt(String::length));

5) Collectors
Collectors.toList(), toSet(), joining(","), summarizingInt, groupingBy, partitioningBy
Example:
Map<Integer, List<String>> byLen =
names.stream().collect(Collectors.groupingBy(String::length));

6) reduce()
int prod = IntStream.of(1,2,3,4).reduce(1, (a,b) -> a*b);

7) Optional + Streams
Optional<String> maybeName = names.stream().findFirst();
String first = maybeName.orElse("N/A");

8) Primitive Streams
double avgLen = names.stream()
.mapToInt(String::length)
.average()
.orElse(0.0);

9) Sorting & Comparators


List<String> sorted = names.stream()
.sorted(Comparator.comparingInt(String::length)
.thenComparing(Comparator.naturalOrder()))
.toList();

10) Files & IO with Streams


try (Stream<String> lines = Files.lines(Path.of("log.txt"))) {
Map<String, Long> freq = lines
.flatMap(line -> Arrays.stream(line.split("\W+")))
.filter(w -> !w.isBlank())
.map(String::toLowerCase)
.collect(Collectors.groupingBy(w -> w, Collectors.counting()));
}

11) Handling Checked Exceptions


@FunctionalInterface
interface ThrowingFunction<T,R> {
R apply(T t) throws Exception;
}

static <T,R> Function<T,R> sneaky(ThrowingFunction<T,R> f) {


return t -> {
try { return f.apply(t); }
catch (Exception e) { throw new RuntimeException(e); }
};
}

List<String> contents = files.stream()


.map(sneaky(path -> Files.readString(Path.of(path))))
.toList();

12) Parallel Streams


long count =
LongStream.rangeClosed(1, 10_000_000)
.parallel()
.filter(n -> n % 2 == 0)
.count();
13) Stateful vs Stateless Operations
Stateless: map, filter, flatMap
Stateful: sorted, distinct, limit

14) Common Patterns


Top-K by score:
record Player(String name, int score) {}
List<Player> top3 = players.stream()
.sorted(Comparator.comparingInt(Player::score).reversed())
.limit(3)
.toList();

Multi-key grouping:
record Txn(String user, String city, double amount) {}
Map<String, Map<String, Double>> totals =
txns.stream().collect(Collectors.groupingBy(
Txn::user,
Collectors.groupingBy(
Txn::city,
Collectors.summingDouble(Txn::amount)
)
));

15) Performance Tips & Pitfalls


- Prefer primitive streams to avoid boxing
- Combine operations to keep pipelines short
- Never mutate external state inside map/filter
- Use toList() (JDK 16+)

16) Testing Streams


static List<String> normalize(List<String> in) {
return in.stream().filter(s -> !s.isBlank()).map(String::trim).toList();
}

17) Mini Projects (practice)


1) Word frequency from file
2) CSV to object grouping
3) Log analyzer (unique visitors per hour)
4) Options P&L simulator

18) Cheat Sheet


// Create
list.stream(); Stream.of(x,y); IntStream.range(a,b);
// Ops
filter(p), map(f), flatMap(f), distinct(), sorted(c), peek(a), limit(n), skip(n)
// Terminal
forEach(a), collect(c), reduce(id,acc,comb), min/max, count
// Collectors
toList(), toSet(), toMap(k,v,merge), joining(delim),
groupingBy(key, downstream), partitioningBy(pred),
// Optional
findFirst()/findAny() -> Optional<T>
// Primitive
mapToInt/Long/Double, average(), sum()
// Files
Files.lines(path)

You might also like