Stream Operations
Stream Filter and Map
Processing collections often requires selecting specific items and transforming them. Stream's filter and map operations let you declaratively express "keep items matching X, then transform each to Y" without manual loops or intermediate collections.
Filtering
The filter operation takes a Predicate<T> and returns a stream containing only elements where the predicate returns true.
import java.util.*;
import java.util.stream.*;
public class Filter {
public static void main(String[] args) {
List<Integer> nums = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8);
int minValue = ;
List<Integer> evens = nums.stream()
.filter(n -> n % 2 == 0)
.collect(Collectors.toList());
System.out.println("evens: " + evens);
List<Integer> large = nums.stream()
.filter(n -> n > minValue)
.collect(Collectors.toList());
System.out.println("large: " + large);
List<Integer> evenAndLarge = nums.stream()
.filter(n -> n % 2 == 0)
.filter(n -> n > 4)
.collect(Collectors.toList());
System.out.println("evenAndLarge: " + evenAndLarge);
}
}
import java.util.*;
import java.util.stream.*;
public class Filter {
public static void main(String[] args) {
List<Integer> nums = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8);
int minValue = ;
List<Integer> evens = nums.stream()
.filter(n -> n % 2 == 0)
.collect(Collectors.toList());
System.out.println("evens: " + evens);
List<Integer> large = nums.stream()
.filter(n -> n > minValue)
.collect(Collectors.toList());
System.out.println("large: " + large);
List<Integer> evenAndLarge = nums.stream()
.filter(n -> n % 2 == 0)
.filter(n -> n > 4)
.collect(Collectors.toList());
System.out.println("evenAndLarge: " + evenAndLarge);
}
}
import java.util.*;
import java.util.stream.*;
public class Filter {
public static void main(String[] args) {
List<Integer> nums = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8);
int minValue = ;
List<Integer> evens = nums.stream()
.filter(n -> n % 2 == 0)
.collect(Collectors.toList());
System.out.println("evens: " + evens);
List<Integer> large = nums.stream()
.filter(n -> n > minValue)
.collect(Collectors.toList());
System.out.println("large: " + large);
List<Integer> evenAndLarge = nums.stream()
.filter(n -> n % 2 == 0)
.filter(n -> n > 4)
.collect(Collectors.toList());
System.out.println("evenAndLarge: " + evenAndLarge);
}
}
Mapping
The map operation takes a Function<T, R> and produces a new stream where each element has been transformed.
import java.util.*;
import java.util.stream.*;
public class Map {
public static void main(String[] args) {
List<String> words = Arrays.asList("apple", "banana", "cherry");
String suffix = ;
List<String> upper = words.stream()
.map(String::toUpperCase)
.collect(Collectors.toList());
System.out.println("upper: " + upper);
List<Integer> lengths = words.stream()
.map(String::length)
.collect(Collectors.toList());
System.out.println("lengths: " + lengths);
List<String> transformed = words.stream()
.map(s -> s.toUpperCase())
.map(s -> s + suffix)
.collect(Collectors.toList());
System.out.println("transformed: " + transformed);
}
}
import java.util.*;
import java.util.stream.*;
public class Map {
public static void main(String[] args) {
List<String> words = Arrays.asList("apple", "banana", "cherry");
String suffix = ;
List<String> upper = words.stream()
.map(String::toUpperCase)
.collect(Collectors.toList());
System.out.println("upper: " + upper);
List<Integer> lengths = words.stream()
.map(String::length)
.collect(Collectors.toList());
System.out.println("lengths: " + lengths);
List<String> transformed = words.stream()
.map(s -> s.toUpperCase())
.map(s -> s + suffix)
.collect(Collectors.toList());
System.out.println("transformed: " + transformed);
}
}
import java.util.*;
import java.util.stream.*;
public class Map {
public static void main(String[] args) {
List<String> words = Arrays.asList("apple", "banana", "cherry");
String suffix = ;
List<String> upper = words.stream()
.map(String::toUpperCase)
.collect(Collectors.toList());
System.out.println("upper: " + upper);
List<Integer> lengths = words.stream()
.map(String::length)
.collect(Collectors.toList());
System.out.println("lengths: " + lengths);
List<String> transformed = words.stream()
.map(s -> s.toUpperCase())
.map(s -> s + suffix)
.collect(Collectors.toList());
System.out.println("transformed: " + transformed);
}
}
Chaining Filter and Map
Filter and map compose naturally into pipelines. You can chain multiple operations, and they execute lazily only when a terminal operation is called.
import java.util.*;
import java.util.stream.*;
public class Chain {
public static void main(String[] args) {
List<String> words = Arrays.asList("apple", "a", "banana", "b", "cherry", "");
int minLength = ;
List<String> result = words.stream()
.filter(s -> s.length() > minLength)
.map(String::toUpperCase)
.collect(Collectors.toList());
System.out.println("result: " + result);
List<Integer> nums = Arrays.asList(-5, -2, 0, 3, 7);
List<Integer> processed = nums.stream()
.map(n -> n * n)
.filter(n -> n > 10)
.collect(Collectors.toList());
System.out.println("processed: " + processed);
List<String> names = Arrays.asList(" Alice ", " bob", "CHARLIE ");
List<String> normalized = names.stream()
.map(String::trim)
.filter(s -> !s.isEmpty())
.map(String::toLowerCase)
.sorted()
.collect(Collectors.toList());
System.out.println("normalized: " + normalized);
}
}
import java.util.*;
import java.util.stream.*;
public class Chain {
public static void main(String[] args) {
List<String> words = Arrays.asList("apple", "a", "banana", "b", "cherry", "");
int minLength = ;
List<String> result = words.stream()
.filter(s -> s.length() > minLength)
.map(String::toUpperCase)
.collect(Collectors.toList());
System.out.println("result: " + result);
List<Integer> nums = Arrays.asList(-5, -2, 0, 3, 7);
List<Integer> processed = nums.stream()
.map(n -> n * n)
.filter(n -> n > 10)
.collect(Collectors.toList());
System.out.println("processed: " + processed);
List<String> names = Arrays.asList(" Alice ", " bob", "CHARLIE ");
List<String> normalized = names.stream()
.map(String::trim)
.filter(s -> !s.isEmpty())
.map(String::toLowerCase)
.sorted()
.collect(Collectors.toList());
System.out.println("normalized: " + normalized);
}
}
FlatMap
When a mapping function produces a stream for each element (e.g., splitting strings into words), use flatMap to flatten the nested streams into a single stream.
import java.util.*;
import java.util.stream.*;
public class Flatmap {
public static void main(String[] args) {
List<List<Integer>> nested = Arrays.asList(
Arrays.asList(1, 2, 3),
Arrays.asList(4, 5),
Arrays.asList(6, 7, 8, 9)
);
List<Integer> flat = nested.stream()
.flatMap(list -> list.stream())
.collect(Collectors.toList());
System.out.println("flat: " + flat);
List<String> sentences = ;
List<String> allWords = sentences.stream()
.flatMap(s -> Arrays.stream(s.split(" ")))
.collect(Collectors.toList());
System.out.println("allWords: " + allWords);
List<Integer> evensFlat = nested.stream()
.flatMap(list -> list.stream())
.filter(n -> n % 2 == 0)
.collect(Collectors.toList());
System.out.println("evensFlat: " + evensFlat);
}
}
import java.util.*;
import java.util.stream.*;
public class Flatmap {
public static void main(String[] args) {
List<List<Integer>> nested = Arrays.asList(
Arrays.asList(1, 2, 3),
Arrays.asList(4, 5),
Arrays.asList(6, 7, 8, 9)
);
List<Integer> flat = nested.stream()
.flatMap(list -> list.stream())
.collect(Collectors.toList());
System.out.println("flat: " + flat);
List<String> sentences = ;
List<String> allWords = sentences.stream()
.flatMap(s -> Arrays.stream(s.split(" ")))
.collect(Collectors.toList());
System.out.println("allWords: " + allWords);
List<Integer> evensFlat = nested.stream()
.flatMap(list -> list.stream())
.filter(n -> n % 2 == 0)
.collect(Collectors.toList());
System.out.println("evensFlat: " + evensFlat);
}
}
Primitive Streams
Use specialized streams for primitives to avoid boxing overhead:
mapToInt,mapToDouble,mapToLongconvert to primitive streamsIntStream,DoubleStream,LongStreamprovide specialized operations
import java.util.*;
import java.util.stream.*;
public class PrimitiveStreams {
public static void main(String[] args) {
List<String> words = Arrays.asList("apple", "banana", "cherry");
int rangeEnd = ;
int totalLength = words.stream()
.mapToInt(String::length)
.sum();
System.out.println("totalLength: " + totalLength);
List<Integer> squares = IntStream.range(1, rangeEnd)
.map(n -> n * n)
.boxed()
.collect(Collectors.toList());
System.out.println("squares: " + squares);
List<Integer> nums = Arrays.asList(1, 2, 3, 4, 5);
double avg = nums.stream()
.mapToDouble(Integer::doubleValue)
.average()
.orElse(0.0);
System.out.println("avg: " + avg);
IntStream.of(3, 1, 4, 1, 5)
.sorted()
.distinct()
.forEach(n -> System.out.print(n + " "));
System.out.println();
}
}
import java.util.*;
import java.util.stream.*;
public class PrimitiveStreams {
public static void main(String[] args) {
List<String> words = Arrays.asList("apple", "banana", "cherry");
int rangeEnd = ;
int totalLength = words.stream()
.mapToInt(String::length)
.sum();
System.out.println("totalLength: " + totalLength);
List<Integer> squares = IntStream.range(1, rangeEnd)
.map(n -> n * n)
.boxed()
.collect(Collectors.toList());
System.out.println("squares: " + squares);
List<Integer> nums = Arrays.asList(1, 2, 3, 4, 5);
double avg = nums.stream()
.mapToDouble(Integer::doubleValue)
.average()
.orElse(0.0);
System.out.println("avg: " + avg);
IntStream.of(3, 1, 4, 1, 5)
.sorted()
.distinct()
.forEach(n -> System.out.print(n + " "));
System.out.println();
}
}
import java.util.*;
import java.util.stream.*;
public class PrimitiveStreams {
public static void main(String[] args) {
List<String> words = Arrays.asList("apple", "banana", "cherry");
int rangeEnd = ;
int totalLength = words.stream()
.mapToInt(String::length)
.sum();
System.out.println("totalLength: " + totalLength);
List<Integer> squares = IntStream.range(1, rangeEnd)
.map(n -> n * n)
.boxed()
.collect(Collectors.toList());
System.out.println("squares: " + squares);
List<Integer> nums = Arrays.asList(1, 2, 3, 4, 5);
double avg = nums.stream()
.mapToDouble(Integer::doubleValue)
.average()
.orElse(0.0);
System.out.println("avg: " + avg);
IntStream.of(3, 1, 4, 1, 5)
.sorted()
.distinct()
.forEach(n -> System.out.print(n + " "));
System.out.println();
}
}
Exercise: Practical.java
Filter a list of products by price range, then map to product names