Java Stream API

Overview :
The Java Stream API facilitates processing sequences of elements, offering operations like filtering, mapping, and reducing. Streams can be used to perform operations in a declarative way, resembling SQL-like operations on data

Key Concepts :
Stream: A sequence of elements supporting sequential and parallel aggregate operations

Intermediate Operations: Operations that return another stream and are lazy (e.g., filter, map)

Terminal Operations: Operations that produce a result or a side-effect and are not lazy (e.g., collect, forEach)

Example Scenario :
Suppose we have a list of Person objects and we want to perform various operations on this list using the Stream API

public class Person { private String name; private int age; private String city; public Person(String name, int age, String city) { this.name = name; this.age = age; this.city = city; } public String getName() { return name; } public int getAge() { return age; } public String getCity() { return city; } @Override public String toString() { return "Person{name='" + name + "', age=" + age + ", city='" + city + "'}"; }
}
Enter fullscreen mode
Exit fullscreen mode

Use Cases :

  1. Filtering
  2. Mapping
  3. Collecting
  4. Reducing
  5. FlatMapping
  6. Sorting
  7. Finding and Matching
  8. Statistics

Filtering : Filtering allows you to select elements that match a given condition

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors; public class Main { public static void main(String[] args) { List<Person> people = Arrays.asList( new Person("Alice", 30, "New York"), new Person("Bob", 20, "Los Angeles"), new Person("Charlie", 25, "New York"), new Person("David", 40, "Chicago") ); // Filter people older than 25 List<Person> filteredPeople = people.stream().filter(person -> person.getAge() > 25) .collect(Collectors.toList()); filteredPeople.forEach(System.out::println); }
}
Enter fullscreen mode
Exit fullscreen mode

Mapping : Mapping transforms each element to another form using a function

public class Main { public static void main(String[] args) { List<Person> people = Arrays.asList( new Person("Alice", 30, "New York"), new Person("Bob", 20, "Los Angeles"), new Person("Charlie", 25, "New York"), new Person("David", 40, "Chicago") ); // Get list of names List<String> names = people.stream() .map(Person::getName) .collect(Collectors.toList()); names.forEach(System.out::println); }
}
Enter fullscreen mode
Exit fullscreen mode

Collecting : Collecting gathers the elements of a stream into a collection or other data structures

public class Main { public static void main(String[] args) { List<Person> people = Arrays.asList( new Person("Alice", 30, "New York"), new Person("Bob", 20, "Los Angeles"), new Person("Charlie", 25, "New York"), new Person("David", 40, "Chicago") ); // Collect names into a set Set<String> uniqueCities = people.stream() .map(Person::getCity).collect(Collectors.toSet()); uniqueCities.forEach(System.out::println); }
}
Enter fullscreen mode
Exit fullscreen mode

Reducing : Reducing performs a reduction on the elements of the stream using an associative accumulation function and returns an Optional

public class Main { public static void main(String[] args) { List<Person> people = Arrays.asList( new Person("Alice", 30, "New York"), new Person("Bob", 20, "Los Angeles"), new Person("Charlie", 25, "New York"), new Person("David", 40, "Chicago") ); // Sum of ages int totalAge = people.stream() .map(Person::getAge).reduce(0, Integer::sum); System.out.println("Total Age: " + totalAge); }
}
Enter fullscreen mode
Exit fullscreen mode

FlatMapping : FlatMapping flattens nested structures into a single stream.

public class Main { public static void main(String[] args) { List<List<String>> namesNested = Arrays.asList( Arrays.asList("John", "Doe"), Arrays.asList("Jane", "Smith"), Arrays.asList("Peter", "Parker") ); List<String> namesFlat = namesNested.stream() .flatMap(List::stream).collect(Collectors.toList()); namesFlat.forEach(System.out::println); }
}
Enter fullscreen mode
Exit fullscreen mode

Sorting : Sorting allows you to sort the elements of a stream

public class Main { public static void main(String[] args) { List<Person> people = Arrays.asList( new Person("Alice", 30, "New York"), new Person("Bob", 20, "Los Angeles"), new Person("Charlie", 25, "New York"), new Person("David", 40, "Chicago") ); // Sort by age List<Person> sortedPeople = people.stream() .sorted(Comparator.comparing(Person::getAge)) .collect(Collectors.toList()); sortedPeople.forEach(System.out::println); }
}
Enter fullscreen mode
Exit fullscreen mode

Finding and Matching :
Finding and matching operations check the elements of a stream to see if they match a given predicate

public class Main { public static void main(String[] args) { List<Person> people = Arrays.asList( new Person("Alice", 30, "New York"), new Person("Bob", 20, "Los Angeles"), new Person("Charlie", 25, "New York"), new Person("David", 40, "Chicago") ); // Find any person living in New York Optional<Person> personInNY = people.stream() .filter(person -> "NewYork".equals(person.getCity())).findAny(); personInNY.ifPresent(System.out::println); // Check if all people are older than 18 boolean allAdults = people.stream() .allMatch(person -> person.getAge() > 18); System.out.println("All adults: " + allAdults); }
} 
Enter fullscreen mode
Exit fullscreen mode

Statistics : The Stream API can also be used to perform various statistical operations like counting, averaging, etc.

public class Main { public static void main(String[] args) { List<Person> people = Arrays.asList( new Person("Alice", 30, "New York"), new Person("Bob", 20, "Los Angeles"), new Person("Charlie", 25, "New York"), new Person("David", 40, "Chicago") ); // Count number of people long count = people.stream().count(); System.out.println("Number of people: " + count); // Calculate average age Double averageAge = people.stream() .collect(Collectors.averagingInt(Person::getAge)); System.out.println("Average Age: " + averageAge); }
} 
Enter fullscreen mode
Exit fullscreen mode

Practical Example :
Here’s a comprehensive example that uses several of the features mentioned above:

import java.util.*;
import java.util.stream.*; public class Main { public static void main(String[] args) { List<Person> people = Arrays.asList( new Person("Alice", 30, "New York"), new Person("Bob", 20, "Los Angeles"), new Person("Charlie", 25, "New York"), new Person("David", 40, "Chicago") ); // Filter, map, sort, and collect List<String> names = people.stream() .filter(person -> person.getAge() > 20) .map(Person::getName) .sorted() .collect(Collectors.toList()); names.forEach(System.out::println); // Find the oldest person Optional<Person> oldestPerson = people.stream() .max(Comparator.comparing(Person::getAge)); oldestPerson.ifPresent(person -> System.out.println("Oldest Person: " + person)); // Group by city Map<String, List<Person>> peopleByCity = people.stream() .collect(Collectors.groupingBy(Person::getCity)); peopleByCity.forEach((city, peopleInCity) -> { System.out.println("People in " + city + ": " + peopleInCity); }); // Calculate total and average age IntSummaryStatistics ageStatistics = people.stream() .collect(Collectors.summarizingInt(Person::getAge)); System.out.println("Total Age: " + ageStatistics.getSum()); System.out.println("Average Age: " + ageStatistics.getAverage()); }
} 
Enter fullscreen mode
Exit fullscreen mode

Summary :
The Java Stream API is a powerful tool for working with collections and data. It allows for:

Filtering: Select elements based on a condition

Mapping: Transform elements

Collecting: Gather elements into collections or other data structures

Reducing: Combine elements into a single result.

FlatMapping: Flatten nested structures.

Sorting: Order elements.

Finding and Matching: Check elements against a condition.

Statistics: Perform statistical operations.

Understanding these features will help you write cleaner, more concise, and more readable code.

Happy Coding…


Discover more from Coursity

Subscribe to get the latest posts sent to your email.

Leave a Comment

Your email address will not be published. Required fields are marked *

Discover more from Coursity

Subscribe now to keep reading and get access to the full archive.

Continue reading

Scroll to Top