1. 程式人生 > >Java8 stream學習

Java8 stream學習

.... 變長參數 err 算法 ace idt 用戶 apple ati

第一個Stream Demo

IDEA裏面寫Stream有個坑

技術分享圖片

技術分享圖片

雖然java文件中沒錯,但是但編譯的時候還是報錯了,

Information:java: javacTask: 源發行版 1.8 需要目標發行版 1.8

解決方法是:perferences -> Build,Execution, Deployment -> Compiler -> Java Compiler
設置相應Module的 bytecode version即可

技術分享圖片

public class StreamDemo {

    public static void main(String[] args) {
        List
<String> list1 = new ArrayList<String>(); list1.add("apple"); list1.add("banana"); list1.add("orange"); list1.add("watermelon"); final Iterator<String> iterator = list1.iterator(); while(iterator.hasNext()) { System.out.println(iterator.next()); }
final long count = list1.stream().filter(str -> str.length() > 5).count(); System.out.println("長度大於5的字符串個數為:" + count); } }

終於成功了......

Stream初步

Stream是元素的集合,這點讓Stream看起來用些類似Iterator;
可以支持順序和並行的對原Stream進行匯聚的操作;


大家可以把Stream當成一個高級版本的Iterator。原始版本的Iterator,用戶只能一個一個的遍歷元素並對其執行某些操作;高級版本的Stream,用戶只要給出需要對其包含的元素執行什麽操作,比如"過濾掉長度大於10的字符串"、"獲取每個字符串的首字母"等,具體這些操作如何應用到每個元素上。

技術分享圖片

圖片就是對於Stream例子的一個解析,可以很清楚的看見:原本一條語句被三種顏色的框分割成了三個部分。紅色框中的語句是一個Stream的生命開始的地方,負責創建一個Stream實例;綠色框中的語句是賦予Stream靈魂的地方,把一個Stream轉換成另外一個Stream,紅框的語句生成的是一個包含所有nums變量的Stream,進過綠框的filter方法以後,重新生成了一個過濾掉原nums列表所有null以後的Stream;藍色框中的語句是豐收的地方,把Stream的裏面包含的內容按照某種算法來匯聚成一個值,例子中是獲取Stream中包含的元素個數。

在此我們總結一下使用Stream的基本步驟:

創建Stream;
轉換Stream,每次轉換原有Stream對象不改變,返回一個新的Stream對象(**可以有多次轉換**);
對Stream進行聚合(Reduce)操作,獲取想要的結果;

最常用的創建Stream有兩種途徑:

通過Stream接口的靜態工廠方法(註意:Java8裏接口可以帶靜態方法);
通過Collection接口的默認方法(默認方法:Default method,也是Java8中的一個新特性,就是接口中的一個帶有實現的方法,後續文章會有介紹)–stream(),把一個Collection對象轉換成Stream

使用Stream靜態方法來創建Stream

1. of方法:有兩個overload方法,一個接受變長參數,一個接口單一值

Stream<Integer> integerStream = Stream.of(1, 2, 3, 5);

Stream<String> stringStream = Stream.of("hehe");
2. generator方法:生成一個無限長度的Stream,其元素的生成是通過給定的Supplier(這個接口可以看成一個對象的工廠,每次調用返回一個給定類型的對象)

Stream.generate(new Supplier<Double>() {
    @Override
    public Double get() {
        return Math.random();
    }
});
Stream.generate(() -> Math.random());
Stream.generate(Math::random);

三條語句的作用都是一樣的,只是使用了lambda表達式和方法引用的語法來簡化代碼。每條語句其實都是生成一個無限長度的Stream,其中值是隨機的。這個無限長度Stream是懶加載,一般這種無限長度的Stream都會配合Stream的limit()方法來用。
3. iterate方法:也是生成無限長度的Stream,和generator不同的是,其元素的生成是重復對給定的種子值(seed)調用用戶指定函數來生成的。其中包含的元素可以認為是:seed,f(seed),f(f(seed))無限循環

Stream.iterate(1, item -> item + 1).limit(10).forEach(System.out::println);

這段代碼就是先獲取一個無限長度的正整數集合的Stream,然後取出前10個打印。千萬記住使用limit方法,不然會無限打印下去。

2.2 通過Collection子類獲取Stream

這個在本文的第一個例子中就展示了從List對象獲取其對應的Stream對象,如果查看Java doc就可以發現Collection接口有一個stream方法,所以其所有子類都都可以獲取對應的Stream對象。

public interface Collection<E> extends Iterable<E> {
    //其他方法省略
    default Stream<E> stream() {
        return StreamSupport.stream(spliterator(), false);
    }
}

Java8 stream學習