Java 8 Stream Samples for Reference

Java 8 Stream Samples which you can refer during your coding

Vicky AV
5 min readNov 20, 2022

1: Generate

// Example 1:Generate 10 Even Numbers

Stream.iterate(0, input -> input + 2)
.limit(10)
.forEach(System.out::println);

// Example 2: Generate 10 Random Numbers

Stream.generate(new Random()::nextInt)
.limit(10)
.forEach(System.out::println);
// Example 3: Generate 100 Student Objects for Testing

public class Student {
private int id;

Student(int id) {
this.id = id;
}
}

List<Student> students = Stream
.iterate(new Student(1), student -> new Student(student.id + 1))
.limit(100)
.collect(Collectors.toList());
// Example 4: Generate 10 Random UUIDs

List<String> infiniteStreamOfRandomUUID = Stream.generate(UUID::randomUUID)
.limit(10)
.map(UUID::toString)
.collect(Collectors.toList());

2: Reduce

// Combine List of names to form a comma separated String

List<String> list = Arrays.asList("Vignesh", "Valli", "Sita Mahalakshmi");

list.stream().reduce((s1, s2) -> s1 + "," + s2)
.ifPresent(System.out::println);

Let’s consider the below list of Employees for all upcoming samples

public class Employee {
private int id;
private String name;
private String city;
private int salary;
private Set<String> departments;

public Employee(int id, String name, String city, int salary, Set<String> departments) {
this.id = id;
this.name = name;
this.city = city;
this.salary = salary;
this.departments = departments;
}

// Getters & Setters to be followed
}

Set<String> deptSet1 = new HashSet<>();
deptSet1.add("SALES");

Set<String> deptSet2 = new HashSet<>();
deptSet2.add("HR");
deptSet2.add("MANAGEMENT");

Set<String> deptSet3 = new HashSet<>();
deptSet3.add("ENGINEERING");
deptSet3.add("MANAGEMENT");

Employee e1 = new Employee(1, "Valli", "Chennai", 55000, deptSet1);
Employee e2 = new Employee(2, "Vicky", "Chennai", 10000, deptSet1);
Employee e3 = new Employee(3, "Sita", "Bengaluru", 25000, deptSet2);
Employee e4 = new Employee(4, "Kriti", "Tokyo", 23450, deptSet3);
Employee e5 = new Employee(5, "Mahalakshmi", "HongKong", 34000, deptSet3);

List<Employee> employees = Arrays.asList(e1, e2, e3, e4, e5);

3: Finding Sum from Stream

// Total salaries of all Employees

// Both of the below examples achieve same result

Integer totalSalaryOfAllEmployees1 = employees.stream()
.map(Employee::getSalary)
.reduce(0, (total, salary) -> total + salary);

Integer totalSalaryOfAllEmployees2 = employees.stream()
.map(Employee::getSalary)
.reduce(0, Integer::sum);

4. Filter

// Filter Employees belong to city Chennai

List<Employee> employeesFromChennai = employees.stream()
.filter(employee -> employee.getCity().equalsIgnoreCase("Chennai"))
.collect(Collectors.toList());

5. Filter with Count

// Count number of Employees belong to city Chennai

long countOfEmployeesFromChennai = employees.stream()
.filter(employee -> employee.getCity().equalsIgnoreCase("Chennai"))
.count();

6. Sort Elements in the Streams

// Sort Employees based on their Salary

// Both of the below examples achieve same result

List<Employee> employeesSortedBasedOnSalary1 = employees.stream()
.sorted((emp1, emp2) -> emp1.getSalary() - emp2.getSalary())
.collect(Collectors.toList());

List<Employee> employeesSortedBasedOnSalary2 = employees.stream()
.sorted(Comparator.comparingInt(Employee::getSalary))
.collect(Collectors.toList());

// Sort List of Integer

List<Integer> sortedNumbers = Stream.of(1, 10, 13, 15, 16, 11, 9, 2, 7, 34)
.sorted()
.collect(Collectors.toList());

7. Skip Few Items from Stream

// When you want to get everything after the given nth element

List<Employee> skipFirstTwoEmployees = employees.stream()
.skip(2)
.collect(Collectors.toList());
// When you want to get first n elements from a List

List<Employee> skipAnythingAfterFirstTwoEmployees = employees.stream()
.limit(2)
.collect(Collectors.toList());

8. Find Min & Max Elements from Stream

// Find Employee with Max salary

// Both of the below examples achieve same result

Optional<Employee> employeeWithMaxSalary1 = employees.stream()
.max((emp1, emp2) -> emp1.getSalary() - emp2.getSalary());

Optional<Employee> employeeWithMaxSalary2 = employees.stream()
.max(Comparator.comparingInt(Employee::getSalary));

// Find Employee with Min salary

// Both of the below examples achieve same result

Optional<Employee> employeeWithMinSalary1 = employees.stream()
.min((emp1, emp2) -> emp1.getSalary() - emp2.getSalary());

Optional<Employee> employeeWithMinSalary2 = employees.stream()
.min(Comparator.comparingInt(Employee::getSalary));

9. Just Do Something on the Stream without disturbing the Stream (PEEK)

// We are just printing Employee before collecting them again in a List

List<Employee> employeesList = employees.stream()
.peek(System.out::println)
.collect(Collectors.toList());

10. Stream to Array

Employee[] employeeArray = employees.stream().toArray(Employee[]::new);

11. Array to Stream

int[] array = {1, 10, 9, 2, 4, 11, 23};

List<Integer> collect = Arrays.stream(array)
.boxed() // boxed() will convert int to Integer
.collect(Collectors.toList());

12. FlatMap

// Each Employee belongs to Set of Departments. Here we collected all 
// Department names in a Set

Set<String> addDepartmentNames = employees.stream()
.map(Employee::getDepartments)
.flatMap(Collection::stream)
.collect(Collectors.toSet());

13. Check if Elements in Stream Matching Certain Condition

// Check if Salary of All Employees in the given list greater than 10k

boolean checkIfSalaryOfAllEmployeeGreaterThan = employees.stream()
.allMatch(employee -> employee.getSalary() > 10000);


// Check if Salary of any one of the Employees in given list greater than 10k

boolean checkIfAnyEmployeeSalaryGreaterThan = employees.stream()
.anyMatch(employee -> employee.getSalary() > 10000);

14. Find Elements from Stream Matching Certain Condition

// Both of the below examples achieve same result

// Find First Employee from the Stream whose Salary is greater than 10000

Optional<Employee> employeeWithSalaryGreaterThan = employees.stream()
.filter(employee -> employee.getSalary() > 10000)
.findAny();

// Find First Employee from the Stream whose Salary is greater than 10000

Optional<Employee> employeeWithSalaryGreaterThan = employees.stream()
.filter(employee -> employee.getSalary() > 10000)
.findFirst();

Note: findAny() & findFirst() will return same result if the stream is not running in parallel

If the stream in parallel, there is no guarantee which element findAny() may return


// Since Parallel Stream is used, random Employee matching given condition
// will be returned

// Find Random Employee from the Stream whose Salary is greater than 10000

Optional<Employee> randomEmployeeWithSalaryGreaterThan2 = employees.parallelStream()
.filter(employee -> employee.getSalary() > 10000)
.findAny();

15. Stream to Map

// Collect Employees by their ID

Map<Integer, Employee> employeeById = employees.stream()
.collect(Collectors.toMap(Employee::getId, Function.identity()));

// Collect Employees by their ID & have them sorted based on the ID

TreeMap<Integer, Employee> employeeById = employees.stream()
.collect(Collectors.toMap(Employee::getId, Function.identity(),
(emp1, emp2) -> emp1, TreeMap::new));

Note: To use Collectors.toMap -> the key we choose (in above case, Employee::getId) should give unique result. If not, it will end up in below Exception

Exception in thread “main” java.lang.IllegalStateException: Duplicate key

If each key is going to result in multiple values, then we need to use Collectors.groupingBy

// Group Employees Based on their City

Map<String, List<Employee>> employeeGroupedByCity = employees.stream()
.collect(Collectors.groupingBy(Employee::getCity));
// Group Employee Names Based on their City

Map<String, List<String>> employeeNameListGroupedByCity = employees.stream()
.collect(Collectors.groupingBy(Employee::getCity,
Collectors.mapping(Employee::getName, Collectors.toList())));
// Count Employees Based on their City. Count will be in Long type

Map<String, Long> employeeCountBasedOnCity = employees.stream()
.collect(Collectors.groupingBy(Employee::getCity, Collectors.counting()));


// Count Employees Based on their City. Count will be in Integer type

Map<String, Integer> employeeCountAsIntegerBasedOnCity = employees.stream()
.collect(Collectors.groupingBy(Employee::getCity,
Collectors.collectingAndThen(Collectors.counting(), Long::intValue)));
// Group Employees based on City & Each Group should be further grouped by 
// their ID

Map<String, Map<Integer, Employee>> groupEmployees = employees.stream()
.collect(Collectors.groupingBy(Employee::getCity,
Collectors.toMap(Employee::getId, Function.identity())));

// Group Employees based on City & Each Group should be further grouped by
// their ID & Set of Departments they work on

Map<String, Map<Integer, Set<String>>> map2 = employees.stream()
.collect(Collectors.groupingBy(Employee::getCity,
Collectors.toMap(Employee::getId, Employee::getDepartments)));
// Collect Highest Paid Employee by City

Map<String, Optional<Employee>> reduceByCityAvgGrade = employees.stream()
.collect(Collectors.groupingBy(Employee::getCity,
Collectors.reducing(BinaryOperator.maxBy(
Comparator.comparing(Employee::getSalary)))));

// Count based on the first character in String

Map<String, Integer> output = Stream.of("My", "Name", "Is", "Mr", "Vicky")
.collect(Collectors.groupingBy(x-> x.substring(0, 1),
Collectors.reducing(0, String::length, Integer::sum)));

Thats all folks !!!

--

--