Streams API: интриги декларативного подхода
Benefits
Internal vs external iteration
More comfortable parallelizm
Основные операции
stream() — от коллекций к стримам.
map() — преобразование.
mapToInt() — преобразование к IntStream
mapToLong() — преобразование к LongStream
mapToDouble() — преобразование к DoubleStream
mapToObj() — преобразование к object stream
boxed() — примитивный тип в обёртку
flatMap() — в плоскую структуру из многовложенной.
mapMulti() — противоположная к flatMap()
filter() — отбрасываем лишние элементы по определенному критерию.
distinct() — отбираем только уникальные элементы.
limit() — ограничиваемся определенным количеством элементов.
forEach() — цикличная обработка.
count() — количество элементов в стриме.
collect() — возвращаем результат в зависимости от коллектора.
reduce() — аггрегированный результат по стриму.
sorted() — сортировка по определенном компаратору.
peek() — выполнение операции над элементом стрима, после того, как тот был получен. Может использоваться для логгирования.
max() -> Optional
min() -> Optional
Операции поиска по стриму:
anyMatch:
идентичный код
boolean hasOrNot = false;
for (String fieldName: fieldNames) {
if (isField(fieldName)) {
hasOrNot = true;
};
}
return hasOrNot;
allMatch:
идентичный код
for (String fieldName: fieldNames) {
if (!isField(fieldName)) return false;
}
return true;
noneMatch:
идентичный код
for (String element : validOut) {
if (name.equals(element)) {
return false;
}
}
return true;
findAny -> Optional
findFirst -> Optional
Дополнительная фильтрация (slicing) доступна с Java 9:
dropWhile
takeWhile
Классификация операций
Основная классификация — промежуточная (intermediate) или завершающая (terminal).
Дополнительная классификация — требование по месту: не требуется дополнительного места; требуется ограниченное постоянное место; требуемое место зависит от размера стрима.
Доступные к вниманию коллекторы
- Collectors.toSet() converts stream to HashSet
– Collectors.toList() converts stream to ArrayList
Collectors.toCollection(LinkedList::new)
return memoryTable.values().stream()
.map(CacheLine::getValue)
.collect(Collectors.toCollection(LinkedList::new));
Collectors.toMap(Key Function, Value Function, DuplicateResolve Function, Constructor) :
list.stream().collect(
Collectors.toMap(
Function.identity(),
key -> key + ".value",
(oldV, newV) -> newV,
TreeMap::new
)
)
Collectors.groupingBy(Classifier Function, Constructor, Another Collector (example, mapping())):
entries.stream().collect(
Collectors.groupingBy(
entry -> entry.getEntryName(),
TreeMap::new,
Collectors.mapping(
entry -> entry.getOwnerAddress().getFlat(),
toSet()
)
)
)
Ваш коллектор нас не устраивает
Разделяем на части
Примитивные, но гордые
Отдельно стоит упомянуть, что для нескольких примитивных типов существуют не boxed стримы — для long, для int и для double.