Java8 新特性之Stream入門以及實戰

什麼是Stream

Stream(流)是一個來自數據源的元素隊列並支持聚合操作

    元素是特定類型的對象,形成一個隊列。 Java中的Stream並不會存儲元素,而是按需計算。
    
    數據源 流的來源。 可以是集合,數組,I/O channel, 產生器generator 等。
    
     類似SQL語句一樣的操作, 比如filter, map, reduce, find, match, sorted等。

和以前的Collection操作不同, Stream操作還有兩個基礎的特徵:

    Pipelining: 中間操作都會返回流對象本身。 這樣多個操作可以串聯成一個管道, 
    如同流式風格(fluent style)。 這樣做可以對操作進行優化, 比如延遲執行(laziness)和短路( short-circuiting)。
    
    內部迭代: 以前對集合遍歷都是通過Iterator或者For-Each的方式,
    顯式的在集合外部進行迭代, 這叫做外部迭代。 Stream提供了內部迭代的方式, 
    通過訪問者模式(Visitor)實現。

直接來上代碼:

 //數據源  多個Stds 對象組成的json數組
        String s="[ { \"stdid\": \"1\", \"score\": \"20\", \"ts\": \"2019-11-15 13:30:10\" }, { \"stdid\": \"2\", \"score\": \"22\", \"ts\": \"2019-11-15 13:31:08\" }, { \"stdid\": \"3\", \"score\": \"20.2\", \"ts\": \"2019-11-14 13:31:20\" }, { \"stdid\": \"4\", \"score\": \"25\", \"ts\": \"2019-11-15 13:33:27\" }, { \"stdid\": \"5\", \"score\": \"20\", \"ts\": \"2019-11-13 13:33:36\" }, { \"stdid\": \"6\", \"score\": \"21.2\", \"ts\": \"2019-11-15 13:33:47\" }, { \"stdid\": \"7\", \"score\": \"26\", \"ts\": \"2019-11-15 13:37:05\" }, { \"stdid\": \"8\", \"score\": \"29\", \"ts\": \"2019-11-15 13:37:31\" }, { \"stdid\": \"9\", \"score\": \"30\", \"ts\": \"2019-11-19 13:37:38\" }, { \"stdid\": \"10\", \"score\": \"12\", \"ts\": \"2019-11-15 13:37:58\" }, { \"stdid\": \"11\", \"score\": \"15\", \"ts\": \"2019-11-22 13:38:04\" }, { \"stdid\": \"12\", \"score\": \"15\", \"ts\": \"2019-11-11 13:38:04\" } ]";

        // 通過GSON 解析成List
        Gson gson=new Gson();
        JsonParser parser = new JsonParser();
        final JsonElement parse = parser.parse(s);
        final JsonArray asJsonArray = parse.getAsJsonArray();
        List<Stds>stds=new ArrayList<>();
        asJsonArray.forEach(jsonElement -> {
            stds.add(gson.fromJson(jsonElement, Stds.class));
        });
        //數據源整理好之後,下面就是正式的流處理實戰了
        //  需求: 取 在時間2019-11-15 13:37:31之前的連續5條數據(按時間排序)的分數前三的平均數
        
        //1.先根據時間排序降序(),
        final double average = stds.stream().
                sorted(Comparator.comparing(Stds::getTs).
                        reversed()).
                filter(stds2 -> stds2.getTs().getTime() < Timestamp.valueOf("2019-11-15 13:37:31").getTime()).
                limit(5).
                sorted(Comparator.comparing(Stds::getScore).reversed()).
                limit(3).
                mapToDouble(e -> e.getScore()).summaryStatistics().getAverage();
        System.out.println(average);

        // collector  處理完流得到的是Stream對象,一般我們會轉爲集合
        final List<Stds> collect = stds.stream().collect(Collectors.toList());
        System.out.println(collect.toString());

Stds 類 省略getter與setter

public class Stds {
    private Integer stdid;

    private Double score;

    private Timestamp ts;
}

總之,用了Stream之後可以減少很多的業務代碼

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章