1. 程式人生 > >試水jdk8 stream

試水jdk8 stream

jdk8出來日子不短了,jdk11都出來了,不過用的最多的不過是1.5罷了。

今年終於鼓起勇氣認真對待它,在18年記錄下學習stream,畫上一個圓。

Java8中有兩大最為重要的改變。第一個是Lambda 表示式;另外一個則是Stream API(java.util.stream.*)。

說說stream吧。前提得有lambda的基礎。

Stream 是Java8 中處理集合的關鍵抽象概念,它可以指定你希望對集合進行的操作,可以執行非常複雜的查詢、過濾和對映資料等操作。使用Stream API 對集合資料進行操作,就類似於使用SQL 執行的資料庫查詢。也可以使用Stream API 來並行執行操作。簡而言之,Stream API 提供了一種高效且易於使用的處理資料的方式。

對stream的操作分為三類。

  1. 建立stream
  2. 中間操作(intermediate operations)
  3. 結束操作(terminal operations):

流程如下圖

建立stream

雖然大部分情況下stream是容器呼叫Collection.stream()方法得到的,但stream和collections有以下不同:

  • 無儲存。stream不是一種資料結構,它只是某種資料來源的一個檢視,資料來源可以是一個數組,Java容器或I/O channel等。
  • 為函數語言程式設計而生。對stream的任何修改都不會修改背後的資料來源,比如對stream執行過濾操作並不會刪除被過濾的元素,而是會產生一個不包含被過濾元素的新stream。
  • 惰式執行。stream上的操作並不會立即執行,只有等到使用者真正需要結果的時候才會執行。
  • 可消費性。stream只能被“消費”一次,一旦遍歷過就會失效,就像容器的迭代器那樣,想要再次遍歷必須重新生成。
Stream API是Java 8中加入的一套新的API,主要用於處理集合操作,不過它的處理方式與傳統的方式不同,
稱為“資料流處理”。流(Stream)類似於關係資料庫的查詢操作,是一種宣告式操作。比如要從資料庫中獲取所有id大於1(filter)的使用者的名稱(map)
並按照使用者的score進行排序(sorted),如果在sql中就會很容易完成,但是在java程式中,在jdk8以前可能要使用很多的if條件,但是在jdk8的stream

流中,我們可以這樣
@Test
    public void test5() {
        List<String> collect = list.stream()
                .filter(p -> p.getId() > 1)
                .sorted(Comparator.comparing(Star::getScore))
                .map(Star::getName)
                .collect((Collectors.toList()));
        System.out.println(collect);
    }

 就是這麼的容易。

        jdk雙冒號 還是比較繞的,看程式碼就明白了。詳細借鑑
package com.test;

import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;

import org.junit.Test;

public class DoubleColonTest {
    
    public static void myPrint(String str) {
        System.out.println("print value : " + str);
    }
    
    /**
     * 不使用雙冒號
     */
    @Test
    public void test1() {
        List<String> list = Arrays.asList("劉德華","黎明","張學友","郭富城");
        list.forEach(p -> myPrint(p));
    }
    
    /**
     * 使用雙冒號
     */
    @Test
    public void test2() {
        List<String> list = Arrays.asList("劉德華","黎明","張學友","郭富城");
        list.forEach(DoubleColonTest::myPrint);
    }
    
    /**
     * 類似於雙冒號
     */
    @Test
    public void test3() {
        List<String> list = Arrays.asList("劉德華","黎明","張學友","郭富城");
        Consumer<String> methodParam = DoubleColonTest::myPrint;
        list.forEach(methodParam);
    }
    
    /**
     * 類似於雙冒號
     */
    @Test
    public void test4() {
        List<String> list = Arrays.asList("劉德華","黎明","張學友","郭富城");
        Consumer<String> methodParam = DoubleColonTest::myPrint;
        list.forEach(p -> methodParam.accept(p));
    }
    
}

 

 

完整程式碼例項

package com.test;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.junit.Before;
import org.junit.Test;

public class TestStream {

    List<Star> list = null;

    @Before
    public void before() {
        list = new ArrayList<Star>() {
            {
                add(new Star(1, "張學友", 11.3));
                add(new Star(3, "劉德華", 4.3));
                add(new Star(2, "黎明", 13.3));
                add(new Star(5, "郭富城", 22.3));
                add(new Star(4, "范冰冰", 2.3));
            }
        };
    }

    /**
     * 遍歷方式
     */
    @Test
    public void test1() {
        System.out.println("第一種---------");
        for (Star Star : list) {
            System.out.println(Star);
        }

        System.out.println("第二種---------");
        list.forEach(p -> System.out.println(p));

        System.out.println("第三種---------");
        list.forEach(System.out::println);

        System.out.println("第四種---------");
        Iterator<Star> iterator = list.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }

        System.out.println("第五種---------");
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }

        System.out.println("第六種---------");
        for (Iterator<Star> it = list.iterator(); it.hasNext();) {
            System.out.println(it.next());
        }

        System.out.println("第七種---------");
        for (int i = 0; i < list.size();) {
            System.out.println(list.get(i));
            i++;
        }

    }

    /**
     * 普通排序
     */
    @Test
    public void test2() {
        Collections.sort(list, new Comparator<Star>() {
            @Override
            public int compare(Star o1, Star o2) {
                return o1.getScore().compareTo(o2.getScore());
            }
        });
        list.forEach(p -> System.out.println(p));
    }

    /**
     * lambda排序
     */
    @Test
    public void test3() {
        Collections.sort(list, (p1, p2) -> p1.getScore().compareTo(p2.getScore()));
        list.forEach(p -> System.out.println(p));
    }

    /**
     * streame排序
     */
    @Test
    public void test4() {
        Stream<Star> stream = list.stream().sorted(Comparator.comparing(Star::getScore));// .forEach(p ->
        stream.forEach(p -> System.out.println(p));
        // list.forEach(p -> System.out.println(p));
    }

    /**
     * 進行過濾操作
     */
    @Test
    public void test5() {
        List<String> collect = list.stream()
                .filter(p -> p.getId() > 1)
                .sorted(Comparator.comparing(p -> p.getScore()))
//                .sorted(Comparator.comparing(Star::getScore))
                .map(Star::getName)
                .collect((Collectors.toList()));
        System.out.println(collect);
    }

}

class Star {
    private Integer id;
    private String name;
    private Double score;

    public Double getScore() {
        return score;
    }

    public void setScore(Double score) {
        this.score = score;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Star() {
        super();
    }

    public Star(Integer id, String name, Double score) {
        super();
        this.id = id;
        this.name = name;
        this.score = score;
    }

    @Override
    public String toString() {
        return "Star [id=" + id + ", name=" + name + ", score=" + score + "]";
    }

}

 

OK,到位,入個門。。。

  借鑑的地址 http://www.nowcode.cn/index.php/2017/02/27/326/ https://www.jianshu.com/p/ceb7bf515c03