12 Common uses of Java Streams
12 Common uses of Java Streams with code examples
Search for a command to run...
12 Common uses of Java Streams with code examples
Nicely written!
While I generally like streams and use them. I feel there's a case of "over use". A lot of times the code isn't less verbose. It also forces us to use objects which is sometimes slower than primitives (until we get Valhalla at least).
Also some chaining makes the code less readable. Worse, it's usually harder to debug... The specialized debugging tools are "nice" but they aren't nearly as powerful/simple as debugging a loop.
I agree that parallelStream shouldn't be in a common use case. But it probably should be mentioned in the advantages.
Backtracking explained step by step with problems

Whether you're a blogger, startup, or business, blogging is a long-term strategy to build a strong presence in front of humans as well as search engines. With these small, easy-to-implement SEO tips, you can increase your blog's reach and traffic. 1....

In the previous article, we looked at the fundamentals of session management. We also looked at two types of access tokens and how both of them are inadequate when it comes to providing strong security along with a good user experience. In this artic...

Introduction Session management is the process of maintaining a session " between a client and a server", "for a user", "for a period of time". A simple session management flow The process can be described as follows: A user authenticates with their...

Java Streams API was introduced in Java 8. Its aim is to provide a less verbose and concise way to carry out common operations on collections of objects.
Although it can be hard to get used to, the Java Streams API is very powerful and can be used to implement complex algorithms.
In this article, we will talk about some common use cases of the Java Streams API.
For those of us not proficient with the Streams API, the goal should be to keep these use cases in mind and whenever we come across one of them, we should try to implement them using Streams rather than the traditional way.
Let's establish some basics first.
stream() - creates a stream from a collectioncollect() - collects the stream into an object. The object can be a collection, primitive, or a custom class.Collectors - a class that provides (a lot of) static methods for collecting streams. We will use some of these below. Refer to the documentation for full reference.These are the most popular stream operations and will be used in the rest of this tutorial.
Let's look at some use cases of streams:
filter() method is used to filter the elements of a Collection based on a condition. Only matching elements are retained.E.g. - Remove all odd numbers from a list.
List<Integer> evenNumbers = originalList.stream()
.filter(n -> n % 2 == 0)
.collect(Collectors.toList());
map() method is used to apply a function to each element of a Collection and return a new Collection of the computed values.E.g. Convert each value to its square.
List<Integer> squares = originalList.stream()
.map(n -> n * n)
.collect(Collectors.toList());
In general, as mentioned above, we can use map() and collect() methods to convert a Collection to another Collection.
Example 1. Create a Map from a List.
Convert a list of strings to a map of string and length.
Map<String, Integer> wordLengths = words.stream()
.collect(Collectors.toMap(
word -> word,
word -> word.length()));
Example 2. Convert list to sets.
This is a common use case for removing duplicates. Further, if we want to put the elements back to a list, we can use the stream() and collect() methods twice.
Convert a list of strings to a list of unique strings.
// if we want to collect to a set
Set<String> uniqueWords = words.stream()
.collect(Collectors.toSet());
// OR
// if we want to start and end as a list
List<String> uniqueWords = words.stream()
.collect(Collectors.toSet()).stream().collect(Collectors.toList());
Example 3. Convert a list of Products to a list of their names. (Flattening)
List<String> productNames = products.stream()
.map(product -> product.getName())
.collect(Collectors.toList());
reduce() method is used to apply a function to each element of a Collection and return a single value.Note that since the reduce() method returns a single value, it is not possible to use it to return a Collection.
E.g. Sum all the values in a list.
int sum = numbers.stream()
.reduce(0, (a, b) -> a + b);
Collectors.groupingBy() method is used to group elements of a Collection based on a condition.E.g. Group all products into lists of Products by their category.
Map<String, List<Product>> productsByCategory = products.stream()
.collect(Collectors.groupingBy(product -> product.getCategory()));
findFirst() and findAny() methods are used to find the first or any element of a Collection that matches a condition.This is typically similar to linear search.
E.g. Find the first word in a list which is longer than 5 characters.
Optional<String> firstLongWord = words.stream()
.filter(word -> word.length() > 5)
.findFirst();
// Note that findFirst() and findAny() methods return Optional<T> objects.
sorted() method is used to sort elements of a Collection.In general, Collections.sort() is enough to sort a Collection. We can use sorted() specially if we want to follow it with another operation.
E.g. Sort a list of numbers in ascending order and then return the first k elements.
List<Integer> topK = numbers.stream()
.sorted()
.limit(k)
.collect(Collectors.toList());
Collectors.partitioningBy() method is used to partition elements of a Collection based on a condition.Partitioning is similar to grouping except it returns two Collections - one for elements matching the condition and one for elements not matching the condition.
E.g. Partition students into passing and failing.
Map<Boolean, List<Student>> passingFailing = students
.stream()
.collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD));
count() method is used to count the number of elements matching a condition.E.g. Count the number of words in a list which are longer than 5 characters.
long count = words.stream()
.filter(word -> word.length() > 5)
.count();
range() method is used to create a range of values.There are special classes for creating streams of particular types - IntStream, LongStream, DoubleStream, and Stream.
These classes are useful when dealing with primitive numeric types. Internally, they use Arrays.stream() to create the stream.
E.g. Create an array of numbers from 0 to 10.
int[] numbers = IntStream.range(0, 10).toArray();
anyMatch(), allMatch(), and noneMatch() are used to match elements of a Collection against a predicate and return a boolean value.E.g. Check for products with a price greater than 10.
// true when all elements match the predicate
boolean allMatch = products.stream()
.allMatch(product -> product.getPrice() > 10);
// true when any element matches the predicate
boolean anyMatch = products.stream()
.anyMatch(product -> product.getPrice() > 10);
// true when no elements match the predicate
boolean noneMatch = products.stream()
.noneMatch(product -> product.getPrice() > 10);
Collectors.joining() method is used to join elements of a Collection into a String.E.g. Join all the words in a list into a single string.
String joinedWords = words.stream()
.collect(Collectors.joining(" "));
Thats it for the common scenarios. There are other less common scenarios you can explore on your own:
filter() method.Thanks for reading. I hope you enjoyed this article. There are many more cases where streams can be used which are not covered in this thread. Feel free to add any common scenario I missed.
If you want to connect with me, you can find me on Twitter.