一种通用的、从流生成复杂值的结构,只要把它传给collect方法,全部的流就均可以使用它了。java
标准类库已经提供了一些有用的收集器,下面示例代码中的收集器都是从java.util.stream.Collectors类中导入的。优化
使用Collectors.toList,还有toSet、toCollection等,这里不须要指定具体的类型,Stream类库在背后自动挑选合适的类型。spa
若是须要指定具体的类型,可使用toCollection,用定制的集合收集元素code
// 使用TreeSet收集元素 Stream.of(1, 2, 3).collect(Collectors.toCollection(TreeSet::new));
能够利用收集器让流生成一个值对象
// 计算每一个元素加1后的平均值 Stream.of(1, 2, 3).collect(Collectors.averagingInt(number -> number + 1));
另一种经常使用的流操做是将其分解为两个集合。可使用收集器partitioningBy,它接收一个流,并将其分红两部分(使用Predicate对象判断一个元素应该属于哪一个部分,并根据布尔值返回一个map到列表)ci
// 分别找出奇数和偶数 Map<Boolean, List<Integer>> collect = Stream.of(1, 2, 3, 4).collect(Collectors.partitioningBy(number -> number % 2 == 0));
数据分组是一种更天然的分割数据操做,与将数据分红true和false不一样,可使用任意值对数据分组。使用groupingBy能够对流进行分组字符串
List<Track> tracks = Arrays.asList(new Track("Bakal", 524), new Track("Violets for Your Furs", 378), new Track("Bakal", 451)); // 根据名称来分组 Map<String, List<Track>> collect = tracks.stream().collect(Collectors.groupingBy(track -> track.getName())); // 使用方法应用优化 Map<String, List<Track>> collect = tracks.stream().collect(Collectors.groupingBy(Track::getName));
不少时候,收集流中的数据都是为了在最后生成一个字符串。可使用joiningget
List<Track> tracks = Arrays.asList(new Track("Bakal", 524), new Track("Violets for Your Furs", 378), new Track("Bakal", 451)); // 使用map提取名称,使用joining获得一个字符串,容许用户指定分割符、前缀、后缀 String collect = tracks.stream() .map(Track::getName) .collect(Collectors.joining(", ", "[", "]"));
可使用第二个收集器,用以收集最终结果的一个子集,这些收集器叫作下游收集器。收集器是生成最终结果的一剂配方,下游收集器是生成部分结果的配方,主收集器中会用到下游收集器。it
List<Track> tracks = Arrays.asList(new Track("Bakal", 524), new Track("Violets for Your Furs", 378), new Track("Bakal", 451)); // 计算每一个分组下的数量 Map<String, Long> collect = tracks.stream() .collect(Collectors.groupingBy(Track::getName, Collectors.counting()));
除此以外,还能够自定义收集器,这里再也不展开io
使用Map的computeIfAbsent方法高效计算斐波那契数列
public class Fibonacci { private static final Map<Integer,Long> cache; static { cache = new HashMap<>(); cache.put(0, 0L); cache.put(1, 1L); } public static long fibonacci(int x) { // 当cache中有时,则直接计算,若是没有则计算并放入cache中 return cache.computeIfAbsent(x, n -> fibonacci(n-1) + fibonacci(n-2)); } public static void main(String[] args) { System.out.println(fibonacci(10)); cache.forEach((key, value) -> { System.out.println(key + ": " + value); }); } }