Java 8 Stream API Explained

1. Introduction

This article explains Java 8 Stream API with different examples. We will learn how to perform different operations using the stream() method.

2. Stream Initialization

Java provides different ways to initialize a stream. Let’s see the most useful ways of creating a stream with examples.

2.1. Stream.empty() Method

We can use Stream.empty() method to create an empty stream. It’s useful when we don’t have any values to fill in the stream and is a better option than returning null.

public Stream<?> stream(List<?> list) {
  if (list == null || list.isEmpty()) {
    return Stream.empty();
  }
  return list.stream();
}

2.2. Java Collection Stream

We can initialize a stream from a Collection, List, or a Set.

public Stream<String> getStreamOfCollection() {
  Collection<String> weekDays = Arrays.asList(new String[] { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" });
  return weekDays.stream();
}

2.3. Java Array Stream

Another way is to initialize a stream from an Array of items.

public Stream<String> getStreamOfArray(){
  return Stream.of("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday");
}

2.4. Java Builder pattern

We can also prepare a Java 8 Stream by applying a Java Builder Pattern. Stream API provides builder() method to add items and finally, we need to call build() to initialize the stream.

public Stream<String> getStreamUsingBuilder(){
  return Stream.<String>builder().add("Sunday").add("Monday").add("Tuesday").build();
}

2.5. Java Regex Pattern Matching

We can use splitAsStream() method under Pattern class to create a stream with sub-string items.

public Stream<String> getStreamUsingString(){
  return Pattern.compile(",").splitAsStream("Sunday, Monday, Tuesday");
}

2.6. Text File Stream

Java Files class provides lines() method to return a stream of the text string for each line in the text file.

public Stream<String> getStreamOfFile(Path path) throws IOException {
  return Files.lines(path);
}

3. Java 8 Stream Operations

After preparing Java 8 stream, we are now ready to perform operations using different possible methods. Let’s see some of the most common use cases by examples.

3.1. Iterate all items

The most common use case is to iterate all items and perform some task over items. We can use forEach() method to iterate all items available in the stream.

public void displayAll(Stream<String> stream) {
    stream.forEach(day -> System.out.println(day));
}

3.2. Filtering items

Another use case is for filtering items and perform operations over the remaining items. We can use filter() method available under Java 8 stream API to filter items.

public void displayAllContainsChar(Stream<String> stream, CharSequence charSequence) {
    stream.filter(item -> item.contains(charSequence)).forEach(item -> System.out.println(item));
}

3.3. Distinct items

Stream API provides distinct() method to filter all duplicate items.

public void displayDistinctItems(Stream<String> stream) {
    stream.distinct().forEach(item -> System.out.println(item));
}

3.4. Map Transformation

Let’s see how can we transform an existing stream to include more results using flatMap() method.

public Stream<String> getStreamOfWords(){
    Collection<String> lines = Arrays.asList("First line of Array", "Second line of Array");
    return lines.stream().flatMap(line -> Arrays.stream(line.split("\\s")));
}

The flatMap transformation creates a new stream containing unique words and all helper streams are closed after this operation.

Note: After transformation, a new stream is created and the stream that runs the operation closed and can’t be reused.

Let’s see how can we use map() method to transform a stream to make all words uppercase.

public Stream<String> getStreamOfUpperCaseWords(Stream<String> stream) {
    return stream.map(word -> word.toUpperCase());
}

3.5. Combining Stream Records

Let’s see how can we reduce/combine all items into a single string using reduce() method.

public String getReducedString(Stream<String> stream) {
    return stream.reduce((item1, item2) -> item1 + item2).get();
}

5. Conclusion

In this article, we learned how to use Java 8 Stream API to iterate, transform, and filter operations over arrays, lists, and collections.

As always the full source can be found over on GitHub.

Leave a Reply

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