歸約和總結(jié)
// 菜單里有多少道菜
menu.stream().count();
// 熱量最高的菜
Comparator<Dish> calComparator = Comparator.comparingInt(Dish::getCalories);
menu.stream().collect(maxBy(calComparator));
// 匯總
menu.stream().collect(summingInt(Dish::getCalories));
// 平均數(shù)
menu.stream().collect(averagingInt(Dish::getCalories));
// 連接字符串
String s = menu.stream().map(Dish::getName).collect(joining(","));
// 廣義上的歸約總結(jié)
// 3個(gè)參數(shù)版本: 初始值、轉(zhuǎn)換函數(shù)、歸約函數(shù)
menu.stream().collect(reducing(0, Dish::getCalories, (i, j) -> i + j));
// 1個(gè)參數(shù)版本
menu.stream().collect(reducing((d1, d2) -> d1.getCalories() > d2.getCalories() ? d1 : d2));
分組
// 按菜的熱量分類
Map<CaloricLevel, List<Dish>> dishByType = menu.stream().collect(groupingBy(dish -> {
if (dish.getCalories() <= 400) return CaloricLevel.DIET;
else return CaloricLevel.FAT;
}));
// 先按類型再按熱量分類
Map<Dish.Type, Map<CaloricLevel, List<Dish>>> dishesByTypeCaloric =
groupingBy(Dish::getType,
groupingBy( dish - > {
if (dish.getCalories() <= 400) return CaloricLevel.DIET;
else return CaloricLevel.FAT;
})));
// 轉(zhuǎn)換收集器的結(jié)果類型
Map<Dish.Type, Dish> maxCaloricByType =
menu.stream().collect(groupingBy(Dish::getType,
// //轉(zhuǎn)換函數(shù)collectingAndThen,接受2個(gè)參數(shù),要轉(zhuǎn)換的收集器maxBy,和轉(zhuǎn)換函數(shù)Optional::get
collectingAndThen(maxBy(comparingInt(Dish::getCalories)),
Optional::get));
// 組合2個(gè)收集器
Map<Dish.Type, Dish> maxCaloricByType =
menu.stream().collect(groupingBy(Dish::getType,
// mapping方法接受2個(gè)參數(shù):一個(gè)是對流中元素做變化的函數(shù),另一個(gè)是收集器負(fù)責(zé)收集函數(shù)結(jié)果
mapping( dish -> {if ...else }, toSet()
)));
分區(qū)
// 分區(qū)是分組的特殊情況,返回boolean值的分組就是分區(qū)
// 例如對素食和非素食按類型分組,得到二級Map
Map<Boolean, Map<Dish.Type, List<Dish>>> vegetarianDishesByType =
menu.stream().collect(
partitioningBy(Dish::isVegetarian,
groupingBy(Dish::getType)));
收集器接口
// T是流的泛型,A是累加器的類型,R是收集操作得到的對象類型
public interface Collector<T, A, R> {
// 建立一個(gè)新的結(jié)果容器
Supplier<A> supplier();
// 例如:
public Supplier<List<T>> supplier() {
return ArrayList::new;
}
// 將元素添加到結(jié)果容器
BiConsumer<A, T> accumulator();
// 例如:
public BiConsumer<List<T>, T> accumulator() {
return (list, item) -> list.add(item);
}
// 對結(jié)果容器應(yīng)用最終轉(zhuǎn)換
Function<A, R> finisher();
// 例如:
public Function<List<T>, List<T>> finisher() {
return Function.identity();
}
// 合并兩個(gè)結(jié)果容器
BinaryOperator<A> combiner();
// 例如:
public BinaryOperator<List<T>> combiner() {
return (list1, list2) -> {
list1.addAll(list2);
return list1;
}
}
// 返回枚舉集合:UNORDERED, CONCURRENT, IDENTITY_FINISH
Set<Characteristics> characteristics();
}
可以不用實(shí)現(xiàn)Collector進(jìn)行自定義收集
menuStream.collect(ArrayList::new, List::add, List::addAll);