流式编程 JDK8 Stream的简单使用方法介绍

本文介绍了JDK8的Stream API,包括其概念、特点、使用示例和常见操作。通过实例展示了如何创建、操作和执行流,如filter、distinct、limit、map等中间操作,以及forEach、toArray、reduce、collect等最终操作。同时,文章讨论了串行流和并行流的使用,帮助理解Stream如何提升代码效率和并行处理能力。
摘要由CSDN通过智能技术生成

JDK8 Stream

文章目录

概念

Stream是JDK8 API的新成员,他允许以声明的方式处理数据集合。

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

特点

代码简洁

函数式编程写出的代码简介且意图明确,使用Stream接口让你从此告别for循环。

多核友好

Java函数式编程使得编写并行程序从未如此简单,你需要的全部就是调用一下方法。

示例

用给出的妹子数据源,按所在地分组,算出妹子的平均薪资

foreach方式

@Test
    public void test1() {
   
        List<Girl> girlList = new ArrayList<>();
        girlList.add(new Girl("小红", 19, 176, "北京", 7500.0));
        girlList.add(new Girl("小玲", 18, 165, "北京", 7000.0));
        girlList.add(new Girl("小冬", 22, 173, "湖南", 6000.0));
        girlList.add(new Girl("小星", 18, 172, "广西", 4500.0));
        girlList.add(new Girl("小莹", 19, 166, "广东", 5300.0));
        girlList.add(new Girl("小北", 20, 169, "广东", 6800.0));
        /**
         * 按所在地分组,算出妹子的平均薪资
         */
        /**
         * 按所在地分组后的 map:
         * {
         * 	  广东 = [Girl {
         * 		name = '小莹', age = 19, height = 166, origin = '广东', salary = 5300.0
         *        }, Girl {
         * 		name = '小北', age = 20, height = 169, origin = '广东', salary = 6800.0
         *    }], 
         *    广西 = [Girl {
         * 		name = '小星', age = 18, height = 172, origin = '广西', salary = 4500.0
         *    }], 
         *    湖南 = [Girl {
         * 		name = '小冬', age = 22, height = 173, origin = '湖南', salary = 6000.0
         *    }], 
         *    北京 = [Girl {
         * 		name = '小红', age = 19, height = 176, origin = '北京', salary = 7500.0
         *    }, Girl {
         * 		name = '小玲', age = 18, height = 165, origin = '北京', salary = 7000.0
         *    }]
         * }
         */
         
        //1.基于所在地分组
        Map<String, List<Girl>> map = new HashMap<>();
        for (Girl girl : girlList) {
   
            List<Girl> list = map.computeIfAbsent(girl.getOrigin(), key -> new ArrayList<>());
            list.add(girl);
        }
        //2.求出不同地方妹子的平均薪资
        for (Map.Entry<String, List<Girl>> entry : map.entrySet()) {
   
            Double sum = 0.0;
            for (Girl girl : entry.getValue()) {
   
                sum+=girl.getSalary();
            }
            System.out.println(entry.getKey()+"女孩的平均薪资是"+(sum/entry.getValue().size()));
        }
    }

运行结果:

广东女孩的平均薪资是6050.0
广西女孩的平均薪资是4500.0
湖南女孩的平均薪资是6000.0
北京女孩的平均薪资是7250.0

Process finished with exit code 0

Stream方式

    @Test
    public void test2() {
   
        List<Girl> girlList = new ArrayList<>();
        girlList.add(new Girl("小红", 19, 176, "北京", 7500.0));
        girlList.add(new Girl("小玲", 18, 165, "北京", 7000.0));
        girlList.add(new Girl("小冬", 22, 173, "湖南", 6000.0));
        girlList.add(new Girl("小星", 18, 172, "广西", 4500.0));
        girlList.add(new Girl("小莹", 19, 166, "广东", 5300.0));
        girlList.add(new Girl("小北", 20, 169, "广东", 6800.0));
        /**
         * 按生源地分组,算出妹子的平均薪资
         */
        girlList.stream().collect(Collectors.groupingBy(girl -> girl.getOrigin(), //1.基于所在地分组
                Collectors.averagingDouble(girl -> girl.getSalary())))        //2.求出不同地方妹子的平均薪资
                .forEach((k,v)-> System.out.println(k+"女孩的平均薪资是"+v));
    }

运行结果:

广东女孩的平均薪资是6050.0
广西女孩的平均薪资是4500.0
湖南女孩的平均薪资是6000.0
北京女孩的平均薪资是7250.0

Process finished with exit code 0

流程

第一步:把数据源转换为Stream对象
第二步:操作Stream流对象
Stream流对象在管道中经过中间操作的处理,最终操作得到前面处理的结果。

操作特性

  1. Stream不存储数据:Stream不是一种数据结构,它只是某种数据源的一个视图,数据源可以是一个数组,Java容器或I/O channel等。
  2. Stream不改变数据源:Stream的任何修改都不会修改背后的数据源,比如对Stream执行过滤操作并不会删除被过滤的元素,而是会产生一个不包含被过滤元素的新Stream。
  3. Stream不可重复使用:Stream只能被“消费”一次,一旦遍历过就会失效,就像容器的迭代器那样,想要再次遍历必须重新生成。

常用操作符

方法 描述 类型
filter() 该方法用于通过设置的条件过滤出元素。 中间操作
distinct() 通过流中元素的 hashCode() 和 equals() 去除重复元素。 中间操作
limit() 获取流中的前n个元素。 中间操作
skip() 获取流中的除去前n个元素的其他元素。 中间操作
sorted() 它使用自然顺序对流的元素进行排序。 中间操作
peek() 对每个元素执行操作并返回一个新的Stream。 中间操作
map() 对流中的所有元素进行统一操作。 中间操作
flatmap() 对流进行扁平化处理。 中间操作
forEach() 遍历流中的每一个元素,执行顺序不一定按照流的顺序。 最终操作
forEachOredered() 遍历流中的每一个元素,执行顺序按照流的顺序。 最终操作
toArray() 将流中的元素放入到一个数组中。 最终操作
reduce() 是把流元素组合起来。它提供一个起始值,然后依照运算规则拼接或者运算。 最终操作
collect() 负责收集流,将流中的结果汇总。结果是由传入collect()中的Collector定义的。 最终操作
min() 返回流中的最小值。 最终操作
max() 返回流中的最大值。 最终操作
count() 返回流中元素的数量。 最终操作
anyMatch() 流中只要有一个元素符合传入的断言,就返回 true,否则返回false,如果流为空,永远返回false。 最终操作
allMatch() 流中所有元素都符合传入的断言时返回 true,否则返回false,流为空时总是返回true。 最终操作
noneMatch() 流中所有元素都不满足传入的断言时返回 true,否则返回false,流为空时总是返回true。 最终操作
findFirst() 返回Optional[流中第一个元素],使用Optional对象.get()可以获取流中第一个元素。若流为空则返回Optional.empty,使用Optional对象.get()会报NoSuchElementException异常。 最终操作
findAny() 返回Optional[流中的任意一个元素],若流为空则返回Optional.empty。 最终操作

具体用法

一、流的创建

1.1使用Collection下的 stream() 和 parallelStream() 方法。
    @Test
    public void create(){
   
        List<String> stringList = Arrays.asList("ad", "", "cbx", "cbx", "", "abf", "ged");
        Stream<String> stream = stringList.stream();    //获取一个串行流
        Stream<String> parallelStream = stringList.parallelStream();    //获取一个并行流
    }

串行流:用于主线程,单线程

并行流:用于多个线程同时运行

1.2 使用Arrays 中的 stream() 方法,将数组转成流。
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值