流的收集器非常有用。可用於將流元素歸約和彙總爲一個值 ,元素分組,元素分區。
1.歸約與彙總
1.1求值
Optional<A> max = Stream.of(new A(4),new A(2),new A(8)).collect(maxBy(comparing(A::getNum)));
Optional<A> min = Stream.of(new A(4),new A(2),new A(8)).collect(minBy(comparing(A::getNum)));
max.ifPresent(a->System.out.println(a.getNum()));
min.ifPresent(a->System.out.println(a.getNum()));
Collectors.summingInt。求和,輸出int 。還有summingLong和SummingDouble方法。 int sum = Stream.of(new A(4),new A(2),new A(8)).collect(summingInt(A::getNum));<!--輸出14-->
Collectors.averagingInt 求平均值。還有averagingLong和averagingDouble。 Double ave = Stream.of(new A(4),new A(2),new A(8)).collect(averagingInt(A::getNum));
summarizingInt方法返回的值中包含了最大值,最小值,和,平均值,數量。還有summarizingLong和summarizingDouble。 IntSummaryStatistics iss = Stream.of(new A(4),new A(2),new A(8)).collect(summarizingInt(A::getNum));
1.2連接字符串
List<String> list = Arrays.asList("hello","world","stream");
String s = list.stream().collect(joining(", "));
List<A> list = Arrays.asList(new A(5),new A(2),new A(3));
int i = list.stream().collect(reducing(0, A::getNum,(a,b)->a+b));
2.分組
List<A> list = Arrays.asList(new A("tom",22),new A("james",22),new A("jack",3));
Map<String, List<A>> map1 = list.stream().collect(groupingBy(A::getName));
多級分組: List<A> list = Arrays.asList(new A("tom",22),new A("tom",15),new A("jack",3));
Map<String, Map<String,List<A>>> map2 = list.stream().collect(
groupingBy(A::getName,groupingBy(a->{if(a.getAge()<18)return "child";
else return "adult";})));
判斷每個分組有多少數量: List<A> list = Arrays.asList(new A("tom",22),new A("tom",15),new A("jack",3));
Map<String, Long> map2 = list.stream().collect(
groupingBy(A::getName,counting()));
得到每個分組年齡最大的那個人: List<A> list = Arrays.asList(new A("tom",22),new A("tom",15),new A("jack",3));
Map<String, Optional<A>> map2 = list.stream().collect(
groupingBy(A::getName,maxBy(comparing(A::getAge))));
Collectors.collectingAndThen 方法可以把結果轉換爲另一種類型。參數爲collector和function。 List<A> list = Arrays.asList(new A("tom",22),new A("tom",15),new A("jack",3));
Map<String, A> map2 = list.stream().collect(
groupingBy(A::getName,collectingAndThen(maxBy(comparing(A::getAge)), Optional::get)));
mapping方法參數爲function和Collector。 List<A> list = Arrays.asList(new A("tom",22),new A("tom",15),new A("jack",3));
Map<String, HashSet<Integer>> map2 = list.stream().collect(
groupingBy(A::getName,mapping(A::getAge, toCollection(HashSet::new))));
3.分區
List<A> list = Arrays.asList(new A("tom",22),new A("tom",15),new A("jack",3));
Map<Boolean,List<A>> map2 = list.stream().collect(partitioningBy(a->a.getAge()>18));
分區的好處在於保留了true和false的兩套列表。4.Collector接口
public interface Collector<T, A, R> {
Supplier<A> supplier();
BiConsumer<A, T> accumulator();
BinaryOperator<A> combiner();
Function<A, R> finisher();
Set<Characteristics> characteristics();
}
T爲收集對象的泛型,A是累加器的類型,累加器是在收集過程中用於累積部分結果的對象。 R是返回對象的類型。supplier方法定義累加器類型。