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
總結一下,就是如下幾類方法:code
1.1 轉換成集合:toList(),toSet(),toMap(),toCollection()對象
1.2 將集合拆分拼接成字符串:joining()排序
1.3 求最大值、最小值、求和、平均值 :maxBy(),minBy(),summingInt(),averagingDouble()ci
1.4 對集合分組:groupingBy(),partitioningBy()字符串
1.5 對數據進行映射:mapping()get
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要更靈活點源碼
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