Essential Java Stream API Operations with Code Examples

Java Stream API: Core Concepts and Practical Usage

Required Imports and Data Model

import java.util.*;
import java.util.stream.Collectors;

class Employee {
    private String empName;
    private int yearsOfService;
    // Constructors, getters, and setters omitted for brevity
}

1. Stream Creation

Multiple methods exist to creating stream instances from various data sources.

Creating Streams from Arrays and Collections

// Create from variable arguments
Stream<String> names = Stream.of("Alex", "Jamie", "Taylor");

// Create an empty stream
Stream<String> emptyStream = Stream.empty();

// Create from a list
List<Integer> numbers = Arrays.asList(1, 2, 3, 4);
Stream<Integer> numStream = numbers.stream();

Primitive Streams

// Integer streams
int[] scores = {85, 92, 78};
IntStream scoreStream = Arrays.stream(scores);
IntStream rangeStream = IntStream.range(1, 10); // 1 to 9
IntStream closedRangeStream = IntStream.rangeClosed(1, 10); // 1 to 10

// Long and Double streams
LongStream idStream = LongStream.of(1001L, 1002L, 1003L);
DoubleStream priceStream = DoubleStream.of(19.99, 29.99, 39.99);

// Random value streams
Random rand = new Random();
IntStream randomInts = rand.ints(5); // 5 random integers
DoubleStream randomDoubles = rand.doubles(3); // 3 random doubles

2. Filtering Elements

The filter operation selects elements based on a predicate.

List<Employee> staff = new ArrayList<>();
staff.add(new Employee("Alex", 3));
staff.add(new Employee("Jordan", 7));
staff.add(new Employee("Casey", 1));

// Filter employees with more than 2 years of service
List<Employee> experienced = staff.stream()
                                  .filter(e -> e.getYearsOfService() > 2)
                                  .collect(Collectors.toList());

3. Element Transformasion

Streams provide map and flatMap for data transformation.

Simple Mapping

// Extract employee names
List<String> employeeNames = staff.stream()
                                 .map(Employee::getEmpName)
                                 .collect(Collectors.toList());

Flattening Collections

List<String> phrases = Arrays.asList("java,stream,api", "filter,map,reduce");

// Using map (returns Stream<Stream<String>>)
List<Stream<String>> mapped = phrases.stream()
                                     .map(p -> Arrays.stream(p.split(",")))
                                     .collect(Collectors.toList());

// Using flatMap (returns flattened Stream<String>)
List<String> flattened = phrases.stream()
                               .flatMap(p -> Arrays.stream(p.split(",")))
                               .collect(Collectors.toList());

4. Data Grouping

The Collectors.groupingBy collector enables data aggregation.

Basic Grouping

List<Employee> team = Arrays.asList(
    new Employee("Alex", "Engineering"),
    new Employee("Jordan", "Marketing"),
    new Employee("Taylor", "Engineering")
);

// Group by department
Map<String, List<Employee>> byDept = team.stream()
    .collect(Collectors.groupingBy(Employee::getDepartment));

Advanced Grouping Operations

// Count employees per department
Map<String, Long> deptCount = team.stream()
    .collect(Collectors.groupingBy(Employee::getDepartment, 
             Collectors.counting()));

// Calculate average service years per department
Map<String, Double> avgService = team.stream()
    .collect(Collectors.groupingBy(Employee::getDepartment,
             Collectors.averagingInt(Employee::getYearsOfService)));

// Find employee with maximum service in each department
Map<String, Optional<Employee>> seniorStaff = team.stream()
    .collect(Collectors.groupingBy(Employee::getDepartment,
             Collectors.maxBy(Comparator
                 .comparing(Employee::getYearsOfService))));

Complex Grouping with Mapping

// Group by service years, then map to employee names
Map<Integer, List<String>> namesByService = team.stream()
    .collect(Collectors.groupingBy(Employee::getYearsOfService,
             Collectors.mapping(Employee::getEmpName,
                 Collectors.toList())));

5. Reduction Operations

The reduce method aggregates stream elements to a single value.

List<Integer> monthlySales = Arrays.asList(15000, 22000, 18000);

// Using reduce with identity value (0 for sum)
int totalSales = monthlySales.stream()
                            .reduce(0, (subtotal, sale) -> subtotal + sale);

// Using reduce without identity (returns Optional)
Optional<Integer> maxSale = monthlySales.stream()
                                       .reduce(Integer::max);

6. Stream Sorting

// Ascending order by years of service
List<Employee> sortedAsc = team.stream()
    .sorted(Comparator.comparing(Employee::getYearsOfService))
    .collect(Collectors.toList());

// Descending order by years of service
List<Employee> sortedDesc = team.stream()
    .sorted(Comparator.comparing(Employee::getYearsOfService).reversed())
    .collect(Collectors.toList());

// Alternative using Collections.sort
Collections.sort(team, Comparator.comparing(Employee::getEmpName));

Tags: java StreamAPI Collectors FunctionalProgramming DataProcessing

Posted on Sat, 29 Aug 2026 16:41:10 +0000 by Verrou