Java 8 Stream Cheatsheet

Convert Array To Map

# Example we have class
class Employment {
 String name;
}

# Usages
List<Employment> employmentList = ....;
Map<String, Employment> employments = employmentList.stream().collect(Collectors.toMap(Employment::getName, Function.identity()));

Merge Lists without duplications

//Example we have class
class CustomerLabel {
 Long id
}
// to merge 2 list
List<CustomerLabel> listA = ...;
List<CustomerLabel> listB = ...;
List<CustomerLabel> merged = new ArrayList<>(
                Stream.of(listA, listB)
                        .flatMap(List::stream)
                      .collect(Collectors.toMap(CustomerLabel::getId,
                                d -> d,
                                (CustomerLabel x, CustomerLabel y) -> x == null ? y : x))
                        .values());

Sum of a List

# Example we have class
class Sale {
 Double totalDollar;
}
# Usages
List<Sale> sales = ....
Double sum = sales.stream().map(Sale::getTotalDollars).reduce(0d, Double::sum);

Calculate Average value

Double double = sales.stream()
    .mapToDouble(WeightChange::getValue)
    .average()
    .orElse(Double.NaN);

Find Max Number in a List

List<Double> numbers = ...
Double max = numbers.stream().max(Double::compareTo).orElse(null);

Find Min Number in a List

List numbers = ...
Double min =numbers.stream().min(Double::compareTo).orElse(null);

Sort an Array of Object

As default, sort is ASC

List<Sale> sales = ...
List<User> sortedList = sales.stream().sort(Comparator.comparingDouble(Sale::getTotalDollar)).collect(Collectors.toList())

Find an element in a List

List<Sale> sales = ...

# find first Sale that have totalDollar > 100
Sale firstElement = sales.stream().filter((sale) -> sale.getTotalDollar() > 100).findFirst().orElse(null)

# find any Sale 
Sale firstElement = sales.stream().filter((sale) -> sale.getTotalDollar() > 100).findAny().orElse(null)

Different between findFirst() vs findAny()

findAnyfindFirst
return any element satisfying the filter, usually the first element in single-thread modealways return the first element satisfying the filter
in parallel mode, it is not guarantee return the first elementin parallel mode, it ensures to return the first element in the list

Parallel mode

Replace .stream() –> .parallelStream()

List<Integer> listOfNumbers = Arrays.asList(1, 2, 3, 4);
listOfNumbers.parallelStream()...

Note:

  • The number of threads in the common pool is equal to the number of processor cores.
  • To change thread pool size, add flag when start application:
    -D java.util.concurrent.ForkJoinPool.common.parallelism=4
  • Sometimes the overhead of managing threads, sources and results is a more expensive operation than doing the actual work.
  • arrays can split cheaply and evenly, while LinkedList has none of these properties. 
  • TreeMap and HashSet split better than LinkedList but not as well as arrays.
  • The merge operation is really cheap for some operations, such as reduction and addition
  • merge operations like grouping to sets or maps can be quite expensive.
  •  As the number of computations increases, the data size required to get a performance boost from parallelism decreases.
  • parallel streams cannot be considered as a magical performance booster. So, sequential streams should still be used as default during development.