- 找出流中最大和最小元素
List<Dish> dishes = Arrays.asList(new Dish(), new Dish(), new Dish());
Dish max = dishes.stream().collect(
Collectors.maxBy(
Comparator.comparing(Dish::getName))).get();
Dish min = dishes.stream().collect(
Collectors.minBy(
Comparator.comparing(Dish::getName))).get();
Dish mmin = dishes.stream().min(Comparator.comparing(Dish::getName)).get();
Dish mmax = dishes.stream().max(Comparator.comparing(Dish::getName)).get();
- 匯總
//匯總
Integer categaries = dishes.stream().collect(Collectors.summingInt(Dish::getCategary));
//summarizingInt 是一個工廠 IntSummaryStatistics返回 max min count sum
IntSummaryStatistics summaryStatistics = dishes.stream().collect(Collectors.summarizingInt(Dish::getCategary));
summaryStatistics.getMax();
summaryStatistics.getMin();
summaryStatistics.getSum();
summaryStatistics.getAverage();
summaryStatistics.getCount();
- 字符串連接
joining工廠方法返回的收集器會把對流中每一個對象應(yīng)用tostring方法得到的字符串連接成一個新的字符串
//字符串操作
List<String> strings = Arrays.asList("hello", "join", "world");
String s = strings.stream().collect(Collectors.joining());
String collect = strings.stream().collect(Collectors.joining(","));
- 分組
一個常見的數(shù)據(jù)庫操作是根據(jù)一個或者多個屬性對集合中的項目進行分組。
//按照菜肴類型分組
Map<String, List<Dish>> typeMaps = dishes.stream().collect(Collectors.groupingBy(Dish::getType));
groupingBy接收一個Function,這個function就是分組函數(shù),按照我們指定的規(guī)則進行分組。這個分組函數(shù)可以是方法引用也可以是一段lambda表達式。
- 多級分組
//多級分組 先根據(jù)類型分組,分組完成之后再按照名稱分組
Map<String, Map<String, List<Dish>>> groupMaps = dishes.stream().collect(
Collectors.groupingBy(dish -> dish.getType(),
Collectors.groupingBy(dish -> dish.getName())));
groupingBy(function,collector)也就是說groupingBy是可以再接收一個collector,這個collector當(dāng)然可以再次進行分組。
- 分區(qū)
分區(qū)的好處在于保留了分區(qū)函數(shù)返回true和false的兩套流元素列表。
//分區(qū)
Map<Boolean, List<Dish>> partionMap = dishes.stream().collect(
Collectors.partitioningBy(dish -> dish.getType().equals("meat")));
//分區(qū)多級函數(shù)
Map<Boolean, Optional<Dish>> meat = dishes.stream().collect(
Collectors.partitioningBy(dish -> dish.getType().equals("meat"),
Collectors.maxBy(Comparator.comparing(Dish::getCategary))));
實際工作中很少用到。
收集器接口
public interface Collector<T,A,R> {
Supplier<A> supplier();
BiConsumer<A,R> accumulator();
Function<A,R> finisher();
BinaryOperator<A> combiner();
Set<Characteristics> characteristics();
}
- T 是流中要收集的項目的泛型
- A是累加器的類型,累加器實在收集過程中用于累計部分結(jié)果的對象
- R 是收集操作得到的對象
理解collector接口申明的方法
- 建立新的結(jié)果容器: supplier
supplier方法必須返回一個結(jié)果為空的Supplier,也就是一個無參函數(shù),在調(diào)用它是會返回一個空的累加器實例。
public Supplier<List<T>> supplier() {
return ()->new ArrayList<T>();
}
- 將元素添加到結(jié)果容器: accumulator
accumulator方法會返回執(zhí)行規(guī)約操作的函數(shù)
public BiComsumer<List<T>,T> accumulator() {
return (list,item)->list.add(item);
}
- 對結(jié)果容器應(yīng)用最終轉(zhuǎn)換:finisher
在遍歷完流之后,finisher方法必須返回在累積過程的最后要調(diào)用的一個函數(shù),以便將累加器對象轉(zhuǎn)換為整個集合操作的最終結(jié)果。
public Function<List<T>,List<T>> finisher() {
return Function.identity();
}
- 合并兩個結(jié)果容器: combiner
combiner返回一個供規(guī)約操作使用的函數(shù),它定義了對流的各個子部分進行并行處理,各個子部分規(guī)約所得的累加器要如何合并。
public BinaryOperator<List<T>> combiner() {
return (list1,list2)->{
list1.addAll(list2);
return list1;
}
}
- characteristics
characteristics 會返回一個不可變的characteristics集合,它定義了收集器的行為。
unordered 規(guī)約結(jié)果不接受流中項目的遍歷和累積順序的影響
concurrent 可以多線程同時調(diào)用
indentity_finish 表明是一個恒等函數(shù)