java8stream使用体验(代码片段)

tanyunlong_nice tanyunlong_nice     2022-12-04     271

关键词:

    最近在工作中发现了对于集合操作转换的神器,java8新特性 stream,学习了下发现有很多值得整理的用法,这里记录下。

一、什么是stream

Stream 作为 Java 8 的一大亮点,它与 java.io 包里的 InputStream 和 OutputStream 是完全不同的概念。它也不同于 StAX 对 XML 解析的 Stream,也不是 Amazon Kinesis 对大数据实时处理的 Stream。Java 8 中的 Stream 是对集合(Collection)对象功能的增强,它专注于对集合对象进行各种非常便利、高效的聚合操作(aggregate operation),或者大批量数据操作 (bulk data operation)。Stream API 借助于同样新出现的 Lambda 表达式,极大的提高编程效率和程序可读性。同时它提供串行和并行两种模式进行汇聚操作,并发模式能够充分利用多核处理器的优势,使用 fork/join 并行方式来拆分任务和加速处理过程。通常编写并行代码很难而且容易出错, 但使用 Stream API 无需编写一行多线程的代码,就可以很方便地写出高性能的并发程序。所以说,Java 8 中首次出现的 java.util.stream 是一个函数式语言+多核时代综合影响的产物。


二、如何使用stream

我们先看一段demo

//Lists是Guava中的一个工具类
List<Integer> nums = Lists.newArrayList(1,null,3,4,null,6);
nums.stream().filter(num -> num != null).count();

stream使用结构如下:



图片就是对于Stream例子的一个解析,可以很清楚的看见:原本一条语句被三种颜色的框分割成了三个部分。红色框中的语句是一个Stream的生命开始的地方,负责创建一个Stream实例;绿色框中的语句是赋予Stream灵魂的地方,把一个Stream转换成另外一个Stream,红框的语句生成的是一个包含所有nums变量的Stream,进过绿框的filter方法以后,重新生成了一个过滤掉原nums列表所有null以后的Stream;蓝色框中的语句是丰收的地方,把Stream的里面包含的内容按照某种算法来汇聚成一个值,例子中是获取Stream中包含的元素个数。


三、用法分类

下面我们通过具体的demo 来看下实际用法吧

forEach() -->对流中的每个元素执行一些操作。
toArray() --> 将流中的元素倾倒入一个数组。
reduce() --> 通过一个二进制操作将流中的元素合并到一起。
collect() --> 将流中的元素倾倒入某些容器,eg:一个Collection或Map.
min() --> 根据一个比较器找到流中元素的最小值。
max() --> 根据一个比较器找到流中元素的最大值。
count() --> 计算流中元素的数量。
anyMatch() --> 判断流中是否至少有一个元素匹配断言。这是一个短路的操作。
allMatch() --> 判断流中是否每一个元素都匹配断言。这是一个短路的操作。
noneMatch()--> 判断流中是否没有一个元素匹配断言。这是一个短路的操作。
findFirst()--> 查找流中的第一个元素。这是一个短路的操作。
findAny() --> 查找流中的任意元素,可能对某些流要比findFirst代价低。这是一个短路的操作


1、filter

  /**
     * filter 对原始 Stream 进行某项测试,通过测试的元素被留下来生成一个新 Stream。
     */
    List<Integer> nums = Lists.newArrayList(1,null,3,4,null,6);
        nums.stream().filter(num -> num != null).count();

2、reduce

/**
         * reduce 是把 Stream 元素组合起来。
         * 它提供一个起始值(种子),然后依照运算规则(BinaryOperator),
         * 和前面 Stream 的第一个、第二个、第 n 个元素组合。
         */
        // 字符串连接,concat = "ABCD"
        String concat = Stream.of("A", "B", "C", "D").reduce("", String::concat);
        // 求最小值,minValue = -3.0
        double minValue = Stream.of(-1.5, 1.0, -3.0, -2.0).reduce(Double.MAX_VALUE, Double::min);
        // 求和,sumValue = 10, 有起始值
        int sumValue = Stream.of(1, 2, 3, 4).reduce(0, Integer::sum);
        // 求和,sumValue = 10, 无起始值
        sumValue = Stream.of(1, 2, 3, 4).reduce(Integer::sum).get();
        // 过滤,字符串连接,concat = "ace"
        concat = Stream.of("a", "B", "c", "D", "e", "F").
                filter(x -> x.compareTo("Z") > 0).
                reduce("", String::concat);

3、limit/skip

/**
         * limit 返回 Stream 的前面 n 个元素;
         * skip 则是扔掉前 n 个元素(它是由一个叫 subStream 的方法改名而来)。
         */
        List<Person> persons = new ArrayList();
        for (int i = 1; i <= 10000; i++) 
            Person person = new Person(i,"name"+i);
            persons.add(person);
        
        List<String> personList2 = persons.stream().
                map(Person::getName).limit(10).skip(3).collect(Collectors.toList());
        System.out.println(personList2);

4、foreach

//forEach 方法接收一个 Lambda 表达式,然后在 Stream 的每一个元素上执行该表达式
// Java 8
roster.stream()
 .filter(p -> p.getGender() == Person.Sex.MALE)
 .forEach(p -> System.out.println(p.getName()));
// Pre-Java 8
for (Person p : roster) 
 if (p.getGender() == Person.Sex.MALE) 
 System.out.println(p.getName());
 


5、match

Stream 有三个 match 方法,从语义上说

allMatch:Stream 中全部元素符合传入的 predicate,返回 true

anyMatch:Stream 中只要有一个元素符合传入的 predicate,返回 true

noneMatch:Stream 中没有一个元素符合传入的 predicate,返回 true

List<Person> persons = new ArrayList();
persons.add(new Person(1, "name" + 1, 10));
persons.add(new Person(2, "name" + 2, 21));
persons.add(new Person(3, "name" + 3, 34));
persons.add(new Person(4, "name" + 4, 6));
persons.add(new Person(5, "name" + 5, 55));
boolean isAllAdult = persons.stream().
 allMatch(p -> p.getAge() > 18);
System.out.println("All are adult? " + isAllAdult);
boolean isThereAnyChild = persons.stream().
 anyMatch(p -> p.getAge() < 12);
System.out.println("Any child? " + isThereAnyChild);

6、sort

/**
         * 对 Stream 的排序通过 sorted 进行,
         * 它比数组的排序更强之处在于你可以首先对 Stream 进行各类 map、filter、limit、skip 甚至 distinct 来减少元素数量后,
         * 再排序,这能帮助程序明显缩短执行时间。
         */
        List<Person> persons = new ArrayList();
       for (int i = 1; i <= 5; i++) 
        Person person = new Person(i, "name" + i);
        persons.add(person);
        
        List<Person> personList2 = persons.stream().limit(2).sorted((p1, p2) -> p1.getName().compareTo(p2.getName())).collect(Collectors.toList());
        System.out.println(personList2);
    

四、实战用法

(1) 根据List创建Map

List<Integer> list = IntStream.range(1, 100).boxed().collect(Collectors.toList());
Map<Integer, Integer> map = list.stream().collect(Collectors.toMap(p -> p, q->q*3));
System.out.println(map);

(2)求列表元素的最大数

List<Integer> list = new Random().ints(-100,100).limit(250).boxed().collect(Collectors.toList());
Optional<Integer> max = list.stream().reduce(Math::max);
max.ifPresent(value -> System.out.println(value));


(3)把所有的姓名大写、排序,再输出

String[] names =  "Fred Edwards", "Anna Cox", "Deborah Patterson", "Ruth Torres", "Shawn Powell",
                "Rose Thompson", "Rachel Barnes", "Eugene Ramirez", "Earl Flores", "Janice Reed", "Sarah Miller",
                "Patricia Kelly", "Carl Hall", "Craig Wright", "Martha Phillips", "Thomas Howard", "Steve Martinez",
                "Diana Bailey", "Kathleen Hughes", "Russell Anderson", "Theresa Perry" ;
Arrays.asList(names)
         .stream()
         .map(String::toUpperCase)
         .sorted().forEach(System.out::println);

(4)依次输入0-9

IntStream.range(0, 10).forEach(value -> System.out.println(value));


(5)根据条件进行分组

Map<Integer, List<Person>> collect = persons.stream().collect(Collectors.groupingBy(Person::getAge));


(6)对所有求平均

Double collect = persons.stream().collect(Collectors.averagingInt(Person::getAge));

参考文献:JAVA8初体验

        Java 8 中的 Streams API 详解









java8stream开发使用(代码片段)

函数式编程-Stream流1.概述1.1为什么学?能够看懂公司里的代码大数量下处理集合效率高代码可读性高消灭嵌套地狱//查询未成年作家的评分在70以上的书籍由于洋流影响所以作家和书籍可能出现重复,需要进行去重List<Bo... 查看详情

java8stream开发使用(代码片段)

函数式编程-Stream流1.概述1.1为什么学?能够看懂公司里的代码大数量下处理集合效率高代码可读性高消灭嵌套地狱//查询未成年作家的评分在70以上的书籍由于洋流影响所以作家和书籍可能出现重复,需要进行去重List<Bo... 查看详情

java8stream流使用场景和常用操作(代码片段)

 JAVA8内置的函数式编程接口应用场景和方式  pojo类对象和默认创建list的方法importlombok.AllArgsConstructor;importlombok.Data;importlombok.NoArgsConstructor;importjava.util.ArrayList;importjava.util.List;@Data@AllArgs 查看详情

java8stream,map,option等函数式编程的使用例子(代码片段)

java8stream,map等函数式编程的一些典型用法例子如下。例子1:数组元素字母小写变大写。List<String>list=Arrays.asList("a","b","c","d");List<String>collect=list.stream().map(String::toUpp 查看详情

java8stream,map,option等函数式编程的使用例子(代码片段)

java8stream,map等函数式编程的一些典型用法例子如下。例子1:数组元素字母小写变大写。List<String>list=Arrays.asList("a","b","c","d");List<String>collect=list.stream().map(String::toUpp 查看详情

关于java8stream的相关使用及解析(代码片段)

文章目录前言一、Stream是什么?二、Stream使用1.源码1.collect2.map/flatMap映射转换3.filter过滤属性4.reduce聚合4.sorted排序总结前言蓦然回首,有好久不能够在休息日里去学习新知识、新技能,也好久没有把遇到的问题记录到... 查看详情

java8stream流

Java8Stream流Java8关于map和flatMap的代码片段思考Java8初体验(二)Stream语法详解distinct()/*返回一个流包含不同的元素(根据equals方法判断,null值并不会报空指针异常,会保留一个null)。对于有序的流保证稳定性,保留最先出现的元... 查看详情

java基础java8stream相关内容的简单总结(代码片段)

文章目录【Java基础】Java8Stream相关内容的简单总结1、创建集合的几个方式2、串行和并行3、遍历4、匹配find/match5、聚合max/min/count6、收集collect(使用Collectors类)7、映射map/flatMap8、筛选filter9、排序sorted10、提取/组合【Java基础】Ja... 查看详情

玩转java8stream,让你代码更高效紧凑简洁(代码片段)

系列文章序号标题文章链接1我使用Lambda表达式将上百行的代码精简到几行https://blog.csdn.net/chenlixiao007/article/details/1063666762玩转Java8Optional,让你代码更紧凑简洁且不再出现空指针https://blog.csdn.net/chenlixiao007/article/details/113358813 查看详情

java8stream开发使用(代码片段)

函数式编程-Stream流1.概述1.1为什么学?能够看懂公司里的代码大数量下处理集合效率高代码可读性高消灭嵌套地狱//查询未成年作家的评分在70以上的书籍由于洋流影响所以作家和书籍可能出现重复,需要进行去重List<Bo... 查看详情

java8streams多个分组依据(代码片段)

我的温度记录是这样的dt|AverageTemperature|AverageTemperatureUncertainty|City|Country|Latitude|Longitude----------+-------------------+-----------------------------+-------+--------+--------+---------1963-01-01| 查看详情

java8stream操作(代码片段)

java8stream操作//获取对象集合中某字段的数字和(不会出现空指针)int=集合对象.stream().mapToInt(集合的对象类名::某字段的get方法).sum()//向对象集合中所有对象放入同一字段值(不会出现空指针)集合对象.forEach(... 查看详情

java8stream操作(代码片段)

java8stream操作//获取对象集合中某字段的数字和(不会出现空指针)int=集合对象.stream().mapToInt(集合的对象类名::某字段的get方法).sum()//向对象集合中所有对象放入同一字段值(不会出现空指针)集合对象.forEach(... 查看详情

java8stream操作(代码片段)

java8stream操作//获取对象集合中某字段的数字和(不会出现空指针)int=集合对象.stream().mapToInt(集合的对象类名::某字段的get方法).sum()//向对象集合中所有对象放入同一字段值(不会出现空指针)集合对象.forEach(... 查看详情

java8stream的这些开发技巧,你值得好好收藏(代码片段)

...以坚持ing来源丨苏三说技术如果有些朋友以前没有使用过java8stream这种链式编程方式做开发,想学习一下。如果有些朋友只学习了一部分用法,想学习更多。如果有些朋友想看看有没有好的示例适用于实际工作当中。那么... 查看详情

java8stream(流)(代码片段)

目录引言一、Stream背景概述1、背景2、概念3、特性 4、Stream流的思想5、 Stream流的好处 二、生成流1、Collection体系集合生成2、Map体系集合生成3、数组生成 三、Stream流中间操作方法1、概念:2、常见方法:3、方法展示加... 查看详情

java8stream的用法总结(代码片段)

1、遍历mapmap.forEach((k,v)->System.out.println("key:value="+k+":"+v));2、map转listmap.entrySet().stream().map(e->newPerson(e.getKey(),e.getValue())).collect(Collectors.toList());3、list转mapMap<Int 查看详情

java8stream之collect()的奇技淫巧(代码片段)

点击关注公众号,实用技术文章及时了解前言本身我是一个比较偏向少使用Stream的人,因为调试比较不方便。但是,不得不说,stream确实会给我们编码带来便捷。所以还是忍不住想分享一些奇技淫巧。正文Stream流其实... 查看详情