Skip to content

Streams ​

Performance Tips ​

Creating Streams in a Non-Optimal Way ​

Avoid creating a stream from a collection every time you need to process it. Instead, create it once and reuse it.

Avoid stateful operations ​

Stateful operations, such as sorted() or distinct(), can cause performance issues. So use them wisely.

Remove duplicates ​

If not explicitly required, remove duplicates.

java
List<String> systems = Arrays.asList("c64", "amiga", "amiga", "lynx");

List<String> uniqueItems = systems.stream()
                                  .distinct()
                                  .collect(Collectors.toList());
// Result: c64, amiga, lynx

Filter before map ​

java
List<String> systems = Arrays.asList("c64", "amiga", "lynx");
List<String> filteredList = list.stream()
                                .filter(s -> "lynx".compareTo(syste)!="lynx")
                                .map(String::toUpperCase)
                                .collect(Collectors.toList());

First remove all not important elements and only map the reduced entities

General Tips ​

Avoid Nullpointer Exceptions ​

You can avoid NPE by filtering them out.

java
List<String> filteredNames = list.stream()
                                 .flatMap(Stream::ofNullable)
                                 .collect(Collectors.toList());
java

List<String> filteredNames = list.stream()
                                 .filter(Objects::nonNull)
                                 .collect(Collectors.toList());

Sequence generator ​

java
Easy way to generate sequences.
Stream.iterate(1, n -> n + 3)
      .limit(6)
      .forEach(System.out::println);
// Result: 1, 4, 7, 10, 13, 16

Post processing of streams ​

You can process a stream, collect the result and made some post processing with collectAndThen

java
long carSales = cars.stream()
                    .collect(Collectors.collectingAndThen(
                      Collectors.averagingDouble(cars::getSalePrice),
                      Math::round));

takeWhile, dropWhile ​

With take while, dropWhile you can slice your collection. The difference to filter is, that filter will evaluate each member of the stream. takeWhile, dropWhile will abort the stream on the first occurrence of an item which does not satisfy the condition. So it can massivly improve the performance on sorted lists. But beware.

java
List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6, 7, 8);
List<Integer> taken = numbers.stream()
                             .takeWhile(n -> n < 5)
                             .collect(Collectors.toList());
// Result [1, 2, 3, 4]
java
List<Integer> numbers = List.of(1, 2, 6, 7, 8);
List<Integer> taken = numbers.stream()
                             .dropWhile(n -> n < 5)
                             .collect(Collectors.toList());
// Result [1, 2]

Collectors.teeing ​

The Collectors.teeing() method is useful when we want to simultaneously process a stream in two different ways and then combine their results. If not using the teeing() method, we would have processed the stream two times

java
List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6, 7, 8);

String result = numbers.stream().collect(
Collectors.teeing(
                  Collectors.averagingInt(Integer::intValue),
                  Collectors.summingInt(Integer::intValue),
                  (average, sum) -> String.format("Average: %.2f, Sum: %d", average, sum)
                 )
);

Contact: M_Bergmann AT gmx.at