Lambda表達式-聚合操作


文章參考自博客:https://www.cnblogs.com/franson-2016/p/5593080.html

以及學習網站:how2java.cn

 

1.傳統方式和聚合操作遍歷數據的不同

傳統遍歷List的方式如下:

for(Hero h:list){
            if(h.getAge()>50 && h.getId()<400)
                System.out.println(h.getName());
        }

而使用了聚合操作的方式如下:

list
                .stream()
                .filter( h-> h.getAge()>50 && h.getId()<400)
                .forEach(h-> System.out.println(h.getName()));

 

2.Stream(流)是什么?

    Stream是對集合的包裝,通常和lambda一起使用。 使用lambdas可以支持許多操作,如 map, filter, limit, sorted, count, min, max, sum, collect 等等。 同樣,Stream使用懶運算,他們並不會真正地讀取所有數據,遇到像getFirst() 這樣的方法就會結束鏈式語法。

   Stream和Collection結構化的數據不同,Stream有一系列的元素

   管道指的是一系列的聚合操作的總和

   管道由三部分組成:管道源中間操作結束操作   

   

(1)管道源: 其可以是一個集合,一個數組,一個生成器函數或一個I / O通道

//管道源是一個集合
        list
                .stream()
                .forEach(h-> System.out.println(h.getName()));

       
//管道源是一個數組
        Hero array[] = list.toArray(new Hero[list.size()]);

        Arrays.stream(array)
                .forEach(h-> System.out.println(h.getName()));

(2)零個或多個中間操作:  每個中間操作會返回一個流,如filter,中間操作時懶操作,不會真正遍歷

         中間操作有很多種,主要分為兩種:

         1.對元素進行篩選:filter(匹配),distinct(去除重復),sorted(自然排序)

                                         sorted(Comparator)(指定排序),limit(保留),skip(忽略)

         2.轉為其他形式的流:mapToDouble(轉為double的流), map(轉換為任意類型的流)

 

(3)結束操作:  例如forEach,會返回非流結果,例如基本類型的值(int,float,double)、對象或者集合,或者在終端操作為forEach的情況下沒有返回值。

          結束操作時才真正進行遍歷行為,前面的中間操作也在這個時候真正的執行。

          常見的結束操作如下:

            forEach()(遍歷每個元素),toArray()(轉換為數組),min(Comparator)(取最小的元素)

            max(Comparator)(取最大的元素),count()(總數),findFirst()(第一個元素)

            

3.具體用例

        首先創建一個100個元素的表,用隨機數填充其年齡和ID

Random r = new Random(System.currentTimeMillis());
        List<Hero> list = new ArrayList<>();
        for (int i = 0; i < 100; i++) {
            list.add(new Hero("hero-"+i,r.nextInt(500),r.nextInt(100)));
        }

然后執行各種中間操作:

        //用filter篩選滿足條件的對象,並進行操作
        list
                .stream()
                .filter(h-> h.getId()<300 && h.getAge()>50)
                .forEach(h-> System.out.println(h));

        //用distinct去除重復元素
        list
                .stream()
                .distinct()
                .forEach(h-> System.out.print(h));

        //用sorted進行排序
        list
                .stream()
                .sorted((h1,h2) -> h1.getAge()>h2.getAge() ? 1:-1)
                .forEach(h-> System.out.println(h));

        //用limit保留三個元素
        list
                .stream()
                .limit(3)
                .forEach(h-> System.out.println(h));

        //用skip忽略前三個元素
        list
                .stream()
                .skip(3)
                .forEach(h-> System.out.println(h));

        //用mapToDouble轉換為Double的Stream
        list
                .stream()
                .mapToDouble(Hero::getAge)
                .forEach(h-> System.out.println(h));

        //轉換為任意類型的Stream
        list
                .stream()
                .map((h)-> h.getName()+"-"+h.getAge()+"-"+h.getId())
                .forEach(h-> System.out.println(h));

 

終端操作(結束操作)的用例如下:

        //用forEach遍歷集合
        list
                .stream()
                .forEach(h-> System.out.println(h));

        //用toArray將表變為數組
        Object[] arrays = list
                .stream()
                .toArray();

        //用min得到最小值
        Hero h1 = list
                .stream()
                .min((hf,hs)->hf.getAge()-hs.getAge())
                .get();

        //用max得到最大值
        Hero h2 =list
                .stream()
                .max((hf,hs) -> hf.getAge()-hs.getAge())
                .get();

        //用count計算流中的數據總數
        long count = list
                .stream()
                .count();

        //用findFirst得到第一個元素
        Hero h3 = list
                .stream()
                .findFirst()
                .get();
    

 

測試用例:

 Hero h = list
                .stream()
                .sorted((h1,h2)-> h1.getAge()>h2.getAge() ? -1:1)
                .skip(2)
                .findFirst()
                .get();

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM