Once you have a stream, flat to apply functions to elements and flatMap to unwrap elements returned internally as Optionals.
Load and convert if not null:
Optional.ofNullable(value).ifPresent(v -> BigDecimal.valueOf(Double.parseDouble(v)));
Filtering and get first match:
listOfElements.stream()
.filter(v -> v.value > 0)
.findFirst()
.orElse(null);
Convert property to comma separated list:
listOfElements.stream()
.map(e -> e.getName())
.collect(Collectors.joining(","));
listOfElements.stream().reduce((acc,s) -> acc + "," + s).orElse("");
Get the length of a list of lists:
listOfLists.stream()
.mapToInt(l -> l.size())
.sum();
Has at least an element with a certain flag:
hasAdmins = listOfElements.stream().anyMatch(e -> e.getFlag().equalsIgnoreCase("ADMIN"));
Unique names:
listOfElements.stream().map(e -> e.getName())
.distinct()
.filter(s -> !s.isEmpty())
.toList();
Extract the last from a sequence:
listOfElements.stream()
.reduce((acc,s) -> s)
.orElse("");
Group elements in a list by some common property:
Map<Side,List<Leg>> legsBySide = legs.stream()
.collect(groupingBy(Leg::getSide,LinkedHashMap::new, toList()));
Filter out null object with null-check:
elements.stream().filter(Objects::nonNull);
Make a single stream of elements from a stream of sublists:
streamOfLists.flatMap(Collection::stream).collect(Collector.toList());
Turn a List<Optional<String>> to a List<String> removing null elements without null checks:
List<Optional<String>> someStrings = ...;
List<String> allPresentStrings = someStrings.stream()
.flatMap(Optional::stream)
.collect(Collectors.toList());
Turn a List<List<String>> to a List<String>:
List<List<String>> someStrings = ...;
List<String> allPresentStrings = someStrings.stream()
.flatMap(List::stream)
.collect(Collectors.toList());
While mapping a stream return multiple elements in one of the steps:
List<String> strings = items.stream()
.flatMap(item -> Streams.of("string1","string2"))
.toList();
Concat mutliple streams:
Streams.concat(stream1,Streams.concat(stream2,stream3))
Group by key and extract the max using another key:
Map<String, Optional<Car>> groupByMaxPrice = carsDetails.stream().collect(
Collectors.groupingBy(
Car::getMake,
Collectors.maxBy(Comparator.comparing(Car::getPrice)
));
More elegant handling of exceptions inside maps, use a function that catches returning an empty optional after an exception, and then flatmap back to the original type the resulting stream of optionals.
public static <V,T> Function<v, Optional<T>> catchAsOptional(Logger logger, Function<V,T> closure){
return param -> {
try{
return Optional.ofNullable(closure.apply(param));
}catch(Exception e){
logger.error(e.getMessage(),e);
return Optional.empty();
}
};
}
...stream()
.map(catchAsOptional(logger,(TypeV v) -> functionThatThrowsReturningT(v, param2)) //Box the function in an optional, empty after an exception
.flatMap(Optional::stream); //Filter out empty optionals and unbox them