Java 8 流Stream 的基本使用

一、简介

Java 8 API添加了一个新的抽象称为流Stream,可以让你以一种声明的方式处理数据。

Stream使用一种类似用SQL语句从数据库查询数据的直观方式来提供一种对Java集合运算和表达的高阶抽象。

Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。

这种风格将要处理的元素集合看作一种流,流在管道中传输,并且可以在管道的节点上进行处理,比如筛选,排序,聚合等。

元素流在管道中经过中间操作(intermediate operation)的处理,最后由最终操作(terminal operation)得到前面处理的结果。

二、什么是 Stream?
Stream(流)是一个来自数据源的元素队列并支持聚合操作

元素:是特定类型的对象,形成一个队列。Java中的Stream并不会存储元素,而是按需计算。

数据源 :流的来源。可以是集合,数组,I/O channel,产生器generator等。

聚合操作: 类似SQL语句一样的操作,比如filter, map, reduce, find,match, sorted等。

和以前的Collection操作不同,Stream操作还有两个基础的特征:

Pipelining::中间操作都会返回流对象本身。这样多个操作可以串联成一个管道,如同流式风格(fluent style)。这样做可以对操作进行优化,比如延迟执行(laziness)和短路( short-circuiting)。 

/**
 * Stream(流)是一个来自数据源的元素队列并支持聚合操作
 *
 * 元素:是特定类型的对象,形成一个队列。Java中的Stream并不会存储元素,而是按需计算。
 *
 * 数据源 :流的来源。可以是集合,数组,I/O channel,产生器generator等。
 *
 * 聚合操作: 类似SQL语句一样的操作,比如filter, map, reduce, find,match, sorted等。
 *
 * 和以前的Collection操作不同,Stream操作还有两个基础的特征:
 *
 * Pipelining::中间操作都会返回流对象本身。这样多个操作可以串联成一个管道,如同流式风格(fluent style)。
 *
 * 这样做可以对操作进行优化,比如延迟执行(laziness)和短路( short-circuiting)。
 * ---------------------
 */
public class StreamTestor {

    public static void main(String[] args) throws Exception {



        List<Task> tasks = Arrays.asList(
            new Task(Status.CLOSED,12),
            new Task(Status.OPEN,34),
            new Task(Status.CLOSED,45)
        );

        /** 1、生成流
         * stream() −为集合创建串行流。
         * parallelStream() − 为集合创建并行流。
         */
        List<String> strings = Arrays.asList("abc","","efg","kij");
        List<String> filtered = strings.stream().filter(s -> !s.isEmpty()).collect(Collectors.toList());
        System.out.println(filtered.toString());
        System.out.println("-------------------------------------------");

        /**
         *  2、forEach
         * Stream 提供了新的方法 'forEach' 来迭代流中的每个数据。以下代码片段使用forEach 输出了10个随机数
         */
        Random random = new Random();
        random.ints(5,10).limit(10).forEach(System.out::println);
        System.out.println("-------------------------------------------");


        /** 3、map
         * map 方法用于映射每个元素到对应的结果,以下代码片段使用 map 输出了元素对应的平方数:
         */

        List<Integer> numbers = Arrays.asList(1,2,3,2,3,4,5);
        // 去对应的平方数

        /**
         * 1、numbers 集合被转换成stream流表示
         * 2、map 将流中数元素映射到新的结果集合
         * 3、distinct 对新集合进行去重
         * 4、Collectors  toList()规约操作,将流转换成集合
         */
        List<Integer> subLists = numbers.stream().map(i -> i*i).distinct().collect(Collectors.toList());
        subLists.forEach(m-> System.out.println(m));
        System.out.println("-------------------------------------------");

        /**
         * 4、filter
         * filter 方法用于通过设置条件过滤出元素。以下代码片段使用filter 方法过滤出空字符串:
         */

        List<String> strs = Arrays.asList("ad","sc","","dc","");
        // 获取空字符串
        long count  = strs.stream().filter(s->!s.isEmpty()).count();
        System.out.println(count);
        System.out.println("-------------------------------------------");


        /** 5.limit
         * limit 方法用于获取指定数量的流。以下代码片段使用 limit 方法打印出 10 条数据:
         */
        List<String> res = strs.stream().filter(s->!s.isEmpty()).limit(1).collect(Collectors.toList());
        res.forEach(System.out::println);
        System.out.println("-------------------------------------------");


        /** 6、sorted
         * sorted 方法用于对流进行排序。以下代码片段使用 sorted 方法对输出的 10 个随机数进行排序:
         *
         */

        Random random1 = new Random();
        random1.ints(1,100).limit(10).sorted().forEach(System.out::println);
        System.out.println("-------------------------------------------");


        /**
         * 7、parallerStream
         * parallelStream 是流并行处理程序的代替方法。以下实例我们使用parallelStream 来输出空字符串的数量:
         */
        List<String> strs2 = Arrays.asList("ad","sc","","dc","");
        long count1 = strs2.parallelStream().filter(s->s.isEmpty()).count();
        System.out.println(count1);
        System.out.println("-------------------------------------------");




        /** 8、collectors
         * Collectors 类实现了很多归约操作,例如将流转换成集合和聚合元素。Collectors可用于返回列表或字符串
         */

        List<String> stringList = Arrays.asList("a","b","","c","d");
        List<String> filter = stringList.stream().filter(s->!s.isEmpty()).collect(Collectors.toList());
       // "筛选列表: "
        filter.forEach(System.out::println);
        String mergeStr = stringList.stream().filter(s->!s.isEmpty()).collect(Collectors.joining(","));
        System.out.println("合并字符串:"+mergeStr);
        System.out.println("-------------------------------------------");

        /** 9、统计
         * 另外,一些产生统计结果的收集器也非常有用。它们主要用于int、double、long等基本类型上,它们可以用来产生类似如下的统计结果。
         */

        List<Integer> numbers2 = Arrays.asList(1,3,46,7,6,7,4,8,9);
        IntSummaryStatistics stat = numbers2.stream().mapToInt(x->x).summaryStatistics();
        System.out.println("最大值:"+stat.getMax());
        System.out.println("最小值:"+stat.getMin());
        System.out.println("平均值:"+stat.getAverage());
        System.out.println("求和:"+stat.getSum());
        System.out.println("-------------------------------------------");

        /**
         * 10、groupby
         * 规约操作中,根据某个条件进行分组
         */


        Map<Status,List<Task> > map = tasks.stream().collect(Collectors.groupingBy(s->s.status));
        System.out.println(map);
        System.out.println("-------------------------------------------");

        /**
         * 11、求各个元素分数在集合中的占比
         */


        double totalPoint = tasks.parallelStream().mapToDouble(s->s.points).sum();
        List<String> result = tasks.stream().map(s->s.points/totalPoint).mapToDouble(w->(long)(w*100)).boxed()
            .map(percentage->percentage+"%").collect(Collectors.toList());
        result.forEach(System.out::println);
        System.out.println("-------------------------------------------");

        /**
         * 文件读取
         * Stream的方法onClose 返回一个等价的有额外句柄的Stream,当Stream的close()方法被调用的时候这个句柄会被执行
         */
        final Path path = new File( "README.md" ).toPath();
        Stream< String > lines = Files.lines(path, StandardCharsets.UTF_8 );
        //lines.onClose( () -> System.out.println("Done!") ).forEach( System.out::println );
        lines.forEach(System.out::println);

    }




    private enum Status {
        OPEN, CLOSED
    };

    private static final class Task {
        private final Status status;
        private final Integer points;

        Task( final Status status, final Integer points ) {
            this.status = status;
            this.points = points;
        }

        public Integer getPoints() {
            return points;
        }

        public Status getStatus() {
            return status;
        }

        @Override
        public String toString() {
            return String.format( "[%s, %d]", status, points );
        }
    }

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值