千家信息网

Java8中Stream API操作的示例分析

发表于:2025-11-20 作者:千家信息网编辑
千家信息网最后更新 2025年11月20日,这篇文章主要介绍了Java8中Stream API操作的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。1.什么是StreamA
千家信息网最后更新 2025年11月20日Java8中Stream API操作的示例分析

这篇文章主要介绍了Java8中Stream API操作的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。

1.什么是StreamAPI?

Java8中有两大最为重要的改变。第一个是 Lambda 表达式;另外一个则是 m Stream API (java.util.stream.*) 。

Stream 是 Java8 中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。

使用Stream API 对集合数据进行操作,就类似于使用 SQL 执行的数据库查询。也可以使用 Stream API 来并行执行操作。简而言之,Stream API 提供了一种高效且易于使用的处理数据的方式。

流 (Stream) 到底是什么 呢 ?

是数据渠道,用于操作数据源(集合、数组等)所生成的元素序列。" 集合讲的是 数据 , 流讲的是 计算 !"

注意 :

  • Stream 自己不会存储元素。

  • Stream 不会改变源对象。相反,他们会返回一个持有结果的新Stream。

  • Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行。

2.Stream API操作的三个步骤

  • 创建Stream:一个数据源(如:集合、数组),获取一个流。

  • 中间操作:一个中间操作链,对数据源的数据进行处理。

  • 终止操作( ( 终端操作) ):一个终止操作,执行中间操作链,并产生结果。

2.1 创建Stream

在Java8 中, Collection 接口被扩展,提供了两个获取流的方法 :

  • default Stream stream() : 返回一个顺序流

  • default Stream parallelStream() : 返回一个并行流

Java8 中的 Arrays 的静态方法 stream() 可以获取数组流:

  • static Stream stream(T[] array): 返回一个流重载形式 , 能够处理对应基本类型的数组 :

  • public static IntStream stream(int[] array)

  • public static LongStream stream(long[] array)

  • public static DoubleStream stream(double[] array)

可以使用静态方法 Stream.of(),通过显示值创建一个流。它可以接收任意数量的参数。

  • public static Stream of(T... values) : 返回一个流

可以使用静态方法 Stream.iterate() 和 Stream.generate(),创建无限流。

  • 迭代 public static Stream iterate(final T seed, final UnaryOperator f)

  • 生成 public static Stream generate(Supplier s)

//创建Stream    @Test    public void test1() {        //1.Collection 提供了两个方法  stream() 与 parallelStream()        List list = new ArrayList<>();        Stream stream1 = list.stream();         //2. 通过 Arrays 中的 stream() 获取一个数组流        String[] strings = new String[10];        Stream stream2 = Arrays.stream(strings);         //3. 通过 Stream 类中静态方法 of()        Stream stream3 = Stream.of("abc","666","???");         //4. 创建无限流        //迭代        Stream stream4 = Stream.iterate(0, (x) -> x + 2);        stream4.limit(5).forEach(System.out::println);         //生成        Stream.generate(() -> Math.random())                .limit(5)                .forEach(System.out::println);    }

2.2 中间操作

多个 中间操作可以连接起来形成一个 流 水 线,除非流水线上触发终止操作,否则 中 间操作 不 会执行 任 何 的 处 理!

而在 终止操作时一次性全部处理 , 称 为 " 惰 性 求 值 "。 常用的中间操作大体上可以分为三类:①筛选与切片;②映射;③排序

2.2.1 中间操作之筛选与切片

下面通过一些代码案例来应用一下。 首先,我们准备一个Employee类,以及一个List集合。

package com.szh.java8; import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor; /** * */@Data@NoArgsConstructor@AllArgsConstructorpublic class Employee {     private Integer id;    private String name;    private Integer age;    private Double salary;     public Employee(Integer id) {        this.id = id;    }     public Employee(Integer id,String name) {        this.id = id;        this.name = name;    } }
List employees = Arrays.asList(        new Employee(1001,"张三",26,6666.66),        new Employee(1002,"李四",50,1111.11),        new Employee(1003,"王五",18,9999.99),        new Employee(1004,"赵六",35,8888.88),        new Employee(1005,"田七",44,3333.33),        new Employee(1005,"田七",44,3333.33),        new Employee(1005,"田七",44,3333.33));

筛选年龄小于35岁的员工信息。 这里每次都是先 println 打印结果,然后进行比较,满足则输出。

//内部迭代,在 Stream API 内部完成    @Test    public void test2() {        //所有的中间操作不会做任何的处理        Stream stream = employees.stream()                                    .filter((e) -> {                                        System.out.println("测试中间操作");                                        return e.getAge() <= 35;                                    });        //只有当做终止操作时,所有的中间操作会一次性的全部执行,称为"惰性求值"        stream.forEach(System.out::println);    }

筛选薪资大于5000的员工信息,但是只保留前两条。

@Test    public void test3() {        employees.stream()                .filter((e) -> {                    System.out.println("短路....");                    return e.getSalary() > 5000;                })                .limit(2)                .forEach(System.out::println);    }

筛选薪资大于5000的员工信息,但是扔掉前两条。

@Test    public void test4() {        employees.stream()                .filter((e) -> e.getSalary() > 5000)                .skip(2)                .forEach(System.out::println);    }

对集合中的所有员工信息做去重处理。

@Test    public void test5() {        employees.stream()                .distinct()                .forEach(System.out::println);    }

2.2.2 中间操作之映射

这里仍然是借助上面案例中的Employee类、List集合完成。

首先对自定义的List集合中的所有字符串进行大写转换,同时对员工集合进行 name 字段的映射处理。

@Test    public void test1() {        List list = Arrays.asList("aaa","bbb","ccc","ddd","eee");        list.stream()            .map((str) -> str.toUpperCase())            .forEach(System.out::println);         System.out.println("--------------------------------------");         employees.stream()                .map(Employee::getName)                .forEach(System.out::println);    }

对List集合中的每个字符串中的每个字符进行遍历输出。(①使用map;②使用flatMap)

这两种方式主要区别就在获取到Stream流之后,流中的泛型不一样了。

我们使用map了话,它会将strList集合中元素以 "aaa"、"bbb"、"ccc" 这样的形式返回,此时Stream流的泛型就仍然是一个Stream流(在这个Stream流中才是我们想要的数据),也就是我们第一次对stream流进行遍历之后,拿到的是一个又一个的Character字符数组,然后还需要再对这个字符数组进行二次遍历(也就是代码上半部分中那两个 forEach)。

如果我们使用flatMap了话,它会将strList集合中元素以 "a'、"b"、"c"、"d" 这样的形式返回,所以此时Stream流的泛型就只是一个Character字符数组,那么一次遍历就可以取出数据了(也就是代码下半部分的那个forEach)。

@Test    public void test2() {        List strList = Arrays.asList("aaa","bbb","ccc","ddd","eee");         Stream> stream1 = strList.stream()                .map(MyTest6::filterCharacter);        stream1.forEach((sm) -> {            sm.forEach(System.out::println);        });         System.out.println("----------------------------------------");         Stream stream2 = strList.stream()                .flatMap(MyTest6::filterCharacter);        stream2.forEach(System.out::println);    }     private static Stream filterCharacter(String str) {        List list = new ArrayList<>();         for (Character character : str.toCharArray()) {            list.add(character);        }         return list.stream();    }

2.2.3 中间操作之排序

对List集合中的字符串进行自然排序。对员工集合中的员工信息进行定制化排序(先按照年龄排序,年龄一样再按照姓名排序)。

@Test    public void test3() {        List strList = Arrays.asList("ccc","aaa","bbb","eee","ddd");        strList.stream()                .sorted()                .forEach(System.out::println);         System.out.println("----------------------------------------");         employees.stream()                .sorted((e1,e2) -> {                    if (e1.getAge().equals(e2.getAge())) {                        return e1.getName().compareTo(e2.getName());                    } else {                        return e1.getAge().compareTo(e2.getAge());                    }                })                .forEach(System.out::println);    }

感谢你能够认真阅读完这篇文章,希望小编分享的"Java8中Stream API操作的示例分析"这篇文章对大家有帮助,同时也希望大家多多支持,关注行业资讯频道,更多相关知识等着你来学习!

数据 数组 处理 员工 字符 方法 排序 信息 篇文章 结果 静态 两个 也就是 代码 字符串 年龄 形式 数据源 田七 生成 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 文明六未登录文明服务器 潍坊平台软件开发外包公司 南岸区技术软件开发服务公司 网络技术公众号名称 服务器常见攻击手段和防护 国家有关网络安全保密文件 专技技术人员网络安全生态 中学网络安全教育班会教案 梦幻西游最近有什么服务器 安全报 的内容数据库 宁波物流软件开发费用 公安机关网络安全部门海口市 软件开发 费用结算 小手拉大手网络安全知识 软件开发项目经理计划书 城厢雅绅网络技术是什么 数据库 规格类型怎么写 手机我的世界服务器锁箱子 APP软件开发外包项目合作 数据库加密函数支持数字签名 十堰有软件开发么 北京大规模软件开发经历 手机我的服务器开了进不去 管理疏通服务器 数据库的数字转文本的方法 南京拼团分销软件开发 洪山哪里有软件开发企业 网络安全类风险 用服务器做订阅节点安全吗 steam连接服务器错误
0