jdk1.8的stream學習之四

今天來學習最后一個操作方法collect
日常流式操作后,需要對結(jié)果處理,則可以用這個方法來實現(xiàn)。

collect(Collector<? super P_OUT, A, R> collector)

這里我們首先要學一下Collectors這個類,這個類里有個靜態(tài)內(nèi)部類是Collector的實現(xiàn)類,也就是說,Collectors類里的靜態(tài)方法內(nèi)部實現(xiàn)都是基于Collector的實現(xiàn)類

Collectors.toCollection(Supplier<C> collectionFactory)

這個方法將流收集為一個實現(xiàn)了collection接口的容器類.如下所示,將一個流轉(zhuǎn)化為一個hashSet.只要是collection接口的實現(xiàn)類,都可以在這里輕松轉(zhuǎn)換。

HashSet<Integer> collect =Stream.of(2,3,6,8).collect(Collectors.toCollection(HashSet::new));

toList()

這個不多說,就是直接將流轉(zhuǎn)化為一個Arraylist對象

toSet()

這個也不多說,轉(zhuǎn)化為一個hashSet對象

joining()

這個不多說,將流中的元素拼接成字符串。流中的元素首先必須先轉(zhuǎn)換為string類型。字符串的拼接是通過StringBuilder::append完成的。

    String collect = Stream.of("hello", " ", "world").collect(Collectors.joining());
    輸出:hello world

joining(分隔符)

這個可以指定分割符號來進行字符串拼接。下面的代碼結(jié)果同上

    String collect = Stream.of("hello", "world").collect(Collectors.joining("  "));
    輸出:hello world

joining(分隔符,前綴,后綴)

這里方法里面可以指定分隔符,然后可以指定字符串的前綴,后綴

    String collect = Stream.of("hello", "world").collect(Collectors.joining(",","{","}"));
    輸出:{hello,world}

mapping(Function<? super T, ? extends U> mapper,Collector<? super U, A, R> downstream) 函數(shù)

這個函數(shù)從源碼的功能來看,mapping函數(shù)接收2個參數(shù),第一個參數(shù)就是一個運算式,第二個參數(shù)是接受第一個參數(shù)運算后的結(jié)果,可以繼續(xù)用Collector去處理。明白了這個數(shù)據(jù)的流向,那么我們來看看怎么用
比如:有一個字符串數(shù)組,想把字符串數(shù)組先轉(zhuǎn)成大寫,然后在拼接。可以有2種實現(xiàn)方式。下面的上下兩種方式效果是一樣的。

    String collect = Stream.of("a","b","c").map(s->s.toUpperCase()).collect(Collectors.joining());
    String collect1 = Stream.of("a","b","c").collect(Collectors.mapping(s -> s.toUpperCase(), Collectors.joining()));
    System.out.println(collect);
    System.out.println(collect1);

collectingAndThen(Collector<T,A,R> downstream,Function<R,RR> finisher)

見名知意,這個操作先把結(jié)果可以用自身函數(shù)處理一遍,然后可以繼續(xù)用第二個函數(shù)把之前一補處理完的函數(shù)繼續(xù)用新函數(shù)再次進行運算
比如如下圖,將一個流處理完成后,想變成一個不可再次一被操作的集合,可以通過下列方式去完成。就是第一個參數(shù)處理的結(jié)果,作為第二個行為參數(shù)的入?yún)?,且一定是一個接受一個入?yún)?,然后進過運算有返回值的一個行為函數(shù),最終結(jié)果是以第二個行為函數(shù)操作的結(jié)果。

    Collection<String> collect = Stream.of("a", "b", "c").collect(Collectors.collectingAndThen(Collectors.toList(), a -> Collections.unmodifiableCollection(a)));
    System.out.println(collect);
    輸出結(jié)果是一個不支持修改的集合。

counting 函數(shù),是一個統(tǒng)計函數(shù),返回流中元素的個數(shù)。

    Long collect = Stream.of("a", "b", "c").collect(Collectors.counting());
    System.out.println(collect);
    輸出結(jié)果是3,代表流中元素個數(shù)是3個

minBy maxBy 分別返回流中按照傳入的比較規(guī)則返回最大最小值。

    Optional<Person> collect = Stream.of(new Person("a", 11), new Person("b", 12), new Person("c", 22)).collect(Collectors.minBy((a, b) -> a.getAge() - b.getAge()));
    Optional<Person> collect1 = Stream.of(new Person("a", 11), new Person("b", 12), new Person("c", 22)).collect(Collectors.minBy((a, b) -> b.getAge() - a.getAge()));
    System.out.println(JSONObject.toJSONString(collect.get()));
    System.out.println(JSONObject.toJSONString(collect1.get()));
    操作返回結(jié)果是:
    {"age":11,"name":"a"}
    {"age":22,"name":"c"}

summingInt() summingLong() summingDouble()

需要傳入一個基本類型的數(shù)字,然后這個函數(shù)會對傳入的數(shù)字進行求和。
如下所示,有3個Person對象,想知道這三個對象的年齡和是多少,則可以通過這個函數(shù)來進行運算。運算過程如下,流中的每一個元素會傳入到函數(shù)中,然后傳入的對象需要轉(zhuǎn)換成對于的基本類型,函數(shù)會將基本類型進行求和。

    Integer collect = Stream.of(new Person("a", 11), new Person("b", 12), new Person("c", 22)).
            collect(Collectors.summingInt(value -> value.getAge()));
    System.out.println(collect);
    操作返回結(jié)果是:
    45

averagingInt() averagingLong() averagingDouble()

需要傳入對應的基本類型,然后函數(shù)內(nèi)部會對傳入的數(shù)字進行求平均. 原理同上,需要將傳入的對象轉(zhuǎn)換為對應的基本類型,最后進行求平均

reducing()

這個函數(shù)和reduce函數(shù)的用法是一樣的。這里再次用3個demo來說明下

    一個參數(shù):
    Optional<Person> collect = Stream.of(new Person("張三", 13), new Person("李四", 13)).
            collect(Collectors.reducing(BinaryOperator.minBy(Comparator.comparing(Person::getAge))));
    System.out.println(collect.get());
    2個參數(shù):
    Integer collect = Stream.of(1,2,3,4,5).
            collect(Collectors.reducing(0,(a,b) -> a+b));
    System.out.println(collect);
    3個參數(shù):
         ArrayList<Integer> integers = Lists.newArrayList(1, 2, 3, 4, 5);
    Integer collect = integers.parallelStream().
            collect(Collectors.reducing(0, e -> (Integer) e, (c, d) -> c + d));
    System.out.println(collect);

groupingBy 分組函數(shù)

分組函數(shù)的目標很簡單,就是基于一定的規(guī)則進行分組。如下所示,對流中的數(shù)據(jù)進行奇數(shù)和偶數(shù)分組。

    ArrayList<Integer> integers = Lists.newArrayList(1, 2, 3, 4, 5,6);
    Map<Integer, List<Integer>> collect = integers.stream().
            collect(Collectors.groupingBy(a -> (a)%2));
    System.out.println(collect);
    輸出結(jié)果如下:{0=[2, 4, 6], 1=[1, 3, 5]}

groupingByConcurrent 很簡單,就是分組后返回一個concurrentMap

這個用法和普通的groupingby是一樣的用法,傳入一個分組的標準。比如按人的年齡分組。如下:

    ArrayList<Person> persons = Lists.newArrayList(new Person("a",11),new Person("b",12),new Person("c",11),new Person("b",14));
    ConcurrentMap<Integer, List<Person>> collect = persons.stream().
            collect(Collectors.groupingByConcurrent(a -> a.getAge()));
    System.out.println(JSONObject.toJSONString(collect));
    輸出如下:
    {11:[{"age":11,"name":"a"},{"age":11,"name":"c"}],12:[{"age":12,"name":"b"}],14:[{"age":14,"name":"b"}]}

partitioningBy 和groupingby返回的不一樣的地方在于,返回的是一個key為布爾類型的key,也就是只能返回true,false兩個key。

比如有幾個人,判斷是否是成年人。

    ArrayList<Person> persons = Lists.newArrayList(new Person("a",11),new Person("b",12),new Person("c",18),new Person("b",19));
    Map<Boolean, List<Person>> collect = persons.stream().
            collect(Collectors.partitioningBy(a -> a.getAge() > 17));
    System.out.println(JSONObject.toJSONString(collect));
    輸出結(jié)果如下:
    {false:[{"age":11,"name":"a"},{"age":12,"name":"b"}],true:[{"age":18,"name":"c"},{"age":19,"name":"b"}]}

toMap 這個可以將流轉(zhuǎn)換成map.

比如同樣還是上面4個人,想用年齡做key,名字做value。成功的將一個對象的list轉(zhuǎn)換成某2個屬性的map集合

    ArrayList<Person> persons = Lists.newArrayList(new Person("a",11),new Person("b",12),new Person("c",18),new Person("b",19));
    Map<Integer, String> collect = persons.stream().
            collect(Collectors.toMap(a -> a.getAge(), b -> b.getName()));
    System.out.println(JSONObject.toJSONString(collect));
    輸出如下:
    {18:"c",19:"b",11:"a",12:"b"}

toConcurrentMap 這個和上面一樣,只是返回的是ConcurrentMap

summarizingInt 統(tǒng)計類型類操作??梢詫⒘髦械脑剞D(zhuǎn)換成int類型。返回一個IntSummaryStatistics對象。這個對象可以做統(tǒng)計,求平均數(shù),最大,最小,和等操作。

比如想求上面列表中人的年齡之和。平均數(shù),最大年齡,最小年齡

    ArrayList<Person> persons = Lists.newArrayList(new Person("a",11),new Person("b",12),new Person("c",18),new Person("b",19));
    IntSummaryStatistics collect = persons.stream().
            collect(Collectors.summarizingInt(a -> a.getAge()));
    System.out.println(collect.getAverage());
    System.out.println(collect.getCount());
    System.out.println(collect.getMax());
    System.out.println(collect.getMin());
    System.out.println(collect.getSum());

這里流操作基本就學完了。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

  • Java 8函數(shù)式編程學習筆記 author:Gavin date:2018/11/09 什么是函數(shù)式編程 在思考...
    安靜點就睡吧閱讀 1,355評論 0 10
  • Lua 5.1 參考手冊 by Roberto Ierusalimschy, Luiz Henrique de F...
    蘇黎九歌閱讀 14,235評論 0 38
  • “#本文參加‘青春大賽’,本人保證本文為本人原創(chuàng),如有問題則與主辦方無關(guān),自愿放棄評優(yōu)評獎資格”。 作 者:嚴...
    涼yaasic閱讀 495評論 2 22
  • 文/向上 山崩地裂 震動了整個大地 晃動的山脈 憾動的河流 驚動了多少人心 牽動了多少情懷 原本美麗可愛的大地 你...
    A向上閱讀 809評論 20 32
  • 俏葉繁花迷欲眼,風輕香暖入心田。 此生惟愿春光駐,常向枝頭對笑妍。
    詩徒兒閱讀 728評論 4 12

友情鏈接更多精彩內(nèi)容