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之后可以减少很多的业务代码

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