Java 8 API添加了一个新的抽象称为流Stream,咱们借助Stream API能够很方便的操做流对象。java
Stream中有两个方法collect和collectingAndThen,能够借助Collectors收集器类对流中的数据进行聚合操做,例如将元素累积到集合中,并根据各类标准对元素进行汇总,分类等操做。app
//获取String集合 List<String> strings = Arrays.asList("ab", "", "bc", "cd", "abcd","", "jkl"); //经过stream操做集合 List<String> stringList = strings.stream() //为集合中的每个元素拼接“???” .map(s -> s += "???") //返回集合 .collect(Collectors.toList());
如代码所示,咱们能够很方便的经过Collectors类对被处理的流数据进行聚合操做,包括并不只限与将处理过的流转换成集合ide
总结一下,就是如下几类方法:spa
1.1 转换成集合:toList(),toSet(),toMap(),toCollection()code
1.2 将集合拆分拼接成字符串:joining()对象
1.3 求最大值、最小值、求和、平均值 :maxBy(),minBy(),summingInt(),averagingDouble()排序
1.4 对集合分组:groupingBy(),partitioningBy()ci
1.5 对数据进行映射:mapping()字符串
public final class Collectors { // 转换成集合 public static <T> Collector<T, ?, List<T>> toList(); public static <T> Collector<T, ?, Set<T>> toSet(); public static <T, K, U> Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper); public static <T, C extends Collection<T>> Collector<T, ?, C> toCollection(Supplier<C> collectionFactory); // 拼接字符串,有多个重载方法 public static Collector<CharSequence, ?, String> joining(CharSequence delimiter); public static Collector<CharSequence, ?, String> joining(CharSequence delimiter, CharSequence prefix, CharSequence suffix); // 最大值、最小值、求和、平均值 public static <T> Collector<T, ?, Optional<T>> maxBy(Comparator<? super T> comparator); public static <T> Collector<T, ?, Optional<T>> minBy(Comparator<? super T> comparator); public static <T> Collector<T, ?, Integer> summingInt(ToIntFunction<? super T> mapper); public static <T> Collector<T, ?, Double> averagingDouble(ToDoubleFunction<? super T> mapper); // 分组:能够分红true和false两组,也能够根据字段分红多组 public static <T, K> Collector<T, ?, Map<K, List<T>>> groupingBy(Function<? super T, ? extends K> classifier); // 只能分红true和false两组 public static <T> Collector<T, ?, Map<Boolean, List<T>>> partitioningBy(Predicate<? super T> predicate); // 映射 public static <T, U, A, R> Collector<T, ?, R> mapping(Function<? super T, ? extends U> mapper, Collector<? super U, A, R> downstream); public static <T, U> Collector<T, ?, U> reducing(U identity, Function<? super T, ? extends U> mapper, BinaryOperator<U> op); }
//接下来的示例代码基于此集合 List<String> strings = Arrays.asList("ab", "s", "bc", "cd", "abcd","sd", "jkl");
//转换成list集合 List<String> stringList = strings.stream().collect(Collectors.toList()); //转换成Set集合 Set<String> stringSet = strings.stream().collect(Collectors.toSet()); //转换成Map集合 Map<String,Object> stringObjectMap = strings.stream() .collect(Collectors.toMap(k -> k, v -> v )); System.out.println(stringList); System.out.println(stringSet); System.out.println(stringObjectMap); //=================打印结果================= [ab, s, bc, cd, abcd, sd, jkl] [ab, bc, cd, sd, s, jkl, abcd] {sd=sd, cd=cd, bc=bc, ab=ab, s=s, jkl=jkl, abcd=abcd}
//joining String str1 = strings.stream() .collect(Collectors.joining("--")); //collectingAndThen String str2 = strings.stream() .collect(Collectors.collectingAndThen( //在第一个joining操做的结果基础上再进行一次操做 Collectors.joining("--"), s1 -> s1 += ",then" )); System.out.println(str1); System.out.println(str2); //=================打印结果================= ab--s--bc--cd--abcd--sd--jkl ab--s--bc--cd--abcd--sd--jkl,then
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5); //最大值 Integer maxValue = list.stream().collect(Collectors.collectingAndThen( //maxBy须要Comparator.comparingInt来肯定排序规则 Collectors.maxBy(Comparator.comparingInt(a -> a)), Optional::get )); //最小值 Integer minValue = list.stream().collect(Collectors.collectingAndThen( //minBy须要Comparator.comparingInt来肯定排序规则 Collectors.minBy(Comparator.comparingInt(a -> a)), Optional::get )); //求和 Integer sumValue = list.stream().collect(Collectors.summingInt(i -> i)); //平均值 Double avgValue = list.stream().collect(Collectors.averagingDouble(i -> i)); System.out.println("列表中最大的数 : " + maxValue); System.out.println("列表中最小的数 : " + minValue); System.out.println("全部数之和 : " + sumValue); System.out.println("平均数 : " + avgValue); //=================打印结果================= 列表中最大的数 : 5 列表中最小的数 : 1 全部数之和 : 15 平均数 : 3.0
虽然这样也能够,可是明显IntSummaryStatistics要更灵活点get
Map<Integer, List<String>> map = strings.stream() //根据字符串长度分组(同理,对对象能够经过某个属性分组) .collect(Collectors.groupingBy(String::length)); Map<Boolean, List<String>> map2 = strings.stream() //根据字符串是否大于2分组 .collect(Collectors.groupingBy(s -> s.length() > 2)); System.out.println(map); System.out.println(map2); //=================打印结果================= {1=[s], 2=[ab, bc, cd, sd], 3=[jkl], 4=[abcd]} {false=[ab, s, bc, cd, sd], true=[abcd, jkl]}
String str = strings.stream().collect(Collectors.mapping( //先对集合中的每个元素进行映射操做 s -> s += ",mapping", //再对映射的结果使用Collectors操做 Collectors.collectingAndThen(Collectors.joining(";"), s -> s += "=====then" ) )); System.out.println(str); //=================打印结果================= ab,mapping;s,mapping;bc,mapping;cd,mapping;abcd,mapping;sd,mapping;jkl,mapping=====then