Java基础之Stream流原理与用法详解

yizhihongxing

Java基础之Stream流原理与用法详解

1. 什么是Stream流?

Stream流是Java 8中引入的一种新的API,它允许我们在集合上进行的函数式操作。它使我们能够以声明式方式处理集合中的元素,而不是直接以循环形式迭代它们。在Java 8之前,Collections类提供了大量用于操作集合的方法。但是,为了使用这些方法,你必须在代码中写出来循环,这增加了代码中的错误可能性。Stream流则可以使我们省略掉这种循环。利用Stream流,我们可以在集合中执行过滤、映射、缩减等一系列操作,而不用写复杂的循环。

2. Stream流的特点

Stream流有以下几个特点:

  • Stream流本质上是一个序列,可以按需计算。
  • Stream流不会修改原始数据源,它会创建一份新的数据源来存储结果。
  • Stream流可以是无限的,也可以是有限的。
  • Stream流可以通过过滤、映射、缩减、排序等操作进行处理。

3. Stream流用法详解

下面我们将逐个解释Stream流中最常见的方法。

3.1 创建一个Stream流

Stream流可以通过两种方式进行创建:

3.1.1 通过集合创建Stream

你可以通过集合的stream()方法获取一个Stream流,该方法返回一个流类型的对象。

List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
Stream<Integer> stream = list.stream();
或
Stream<Integer> stream = Arrays.stream(new Integer[]{1, 2, 3, 4, 5});

3.1.2 通过Stream.of()方法创建Stream

你可以通过Stream类的of()方法,将元素转化为Stream流。

Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);

3.2 中间操作

在使用Stream流时,可以通过多种中间操作对集合元素进行处理和转换。

3.2.1 filter()方法

filter()方法用于对Stream流中的元素进行过滤。该方法接收一个Lambda表达式,该表达式的计算结果必须是一个boolean类型的值(true或者false)。如果表达式返回true,则元素会被保留在Stream流中;如果返回false,则元素会被过滤掉。

Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
stream.filter(num -> num % 2 == 0)
      .forEach(System.out::println);

上述代码将筛选出Stream中的偶数,输出结果为:

2
4

3.2.2 map()方法

map()方法用于将Stream流中的元素按照指定的方式进行转换,该方法接收一个Lambda表达式,它将?入的元素转化为另?一个元素,输出这个结果。

Stream<String> stream = Stream.of("hello world", "good morning", "hi");
stream.map(value -> value.toUpperCase())
      .forEach(System.out::println);

上述代码将Stream中的每个字符串元素转换为大写形式,输出结果为:

HELLO WORLD
GOOD MORNING
HI

3.2.3 limit()方法

limit()方法用于截取Stream流中的前n个元素。n的值由你指定。例如:

Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
stream.limit(3)
      .forEach(System.out::println);

输出结果:

1
2
3

3.2.4 sorted()方法

sorted()方法用于对Stream流中的元素进行排序。当然,排序的时候需要指定排序规则,你可以在方法中传递一个Comparator对象或者使用自然排序(自然排序是指比较元素是否实现了Comparable接口,如果实现了就进行比较)。

Stream<Integer> stream = Stream.of(3, 1, 4, 2, 5);
stream.sorted()
      .forEach(System.out::println);
或
Stream<String> stream = Stream.of("c", "a", "b", "d");
stream.sorted((a, b) -> a.compareTo(b))
      .forEach(System.out::println);

输出结果:

1
2
3
4
5
a
b
c
d

3.2.5 distinct()方法

distinct()方法用于去重Stream流中的元素。该方法将重复的元素去掉,只留下不同的元素。去重的规则是使用元素的equals()方法进行比较。

Stream<Integer> stream = Stream.of(1, 2, 3, 2, 4, 5, 4, 6);
stream.distinct()
      .forEach(System.out::println);

输出结果:

1
2
3
4
5
6

3.2.6 peek()方法

peek()方法用于Stream流操作时调试,它可以在Stream流每个元素执行完操作后,在不修改流中元素的情况下输出某些信息。peek()方法的主要目的是用来调试,在开发时排查问题。

Stream<Integer> stream = Stream.of(1, 2, 3);
stream.peek(System.out::println)
      .forEach(System.out::println);

输出结果:

1
1
2
2
3
3

3.3 终止操作

在Stream流的处理完成后,需要执行终止操作才能将Stream流处理完成,终止操作将最终的结果输出到目标中。

3.3.1 forEach()方法

forEach()方法用于对Stream流的每个元素进行执行操作,通常和中间操作配合使用,可以完成一些任务。

Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
stream.filter(num -> num % 2 == 0)
      .forEach(System.out::println);

上述代码将筛选出Stream中的偶数,并将筛选结果输出,输出结果为:

2
4

3.3.2 count()方法

count()方法用于对Stream流中的元素数进行统计。该方法返回一个long类型的值,表示Stream流中元素的个数。

Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
long count = stream.count();
System.out.println(count);

输出结果:

5

好了,以上就是Stream流的详细用法介绍,如果你还想深入了解Stream流的其他用法,可以查阅Java 8官方文档。

4. 示例说明

下面我们通过两个示例来详细说明Stream流的使用。

4.1 Stream流用于对List进行筛选

List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> result = list.stream()
                            .filter(num -> num % 2 == 0)
                            .collect(Collectors.toList());
System.out.println(result);

上述代码将筛选出list中的偶数元素,并将结果输出,输出结果为:

[2, 4]

4.2 Stream流用于对Map进行筛选

Map<String, Integer> map = new HashMap<>();
map.put("a", 1);
map.put("b", 2);
map.put("c", 3);
map.put("d", 4);
map.put("e", 5);

Map<String, Integer> result = map.entrySet().stream()
                                    .filter(entry -> entry.getValue() % 2 == 0)
                                    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
System.out.println(result);

上述代码将筛选出map中的值为偶数的key-value键值对,并将结果输出,输出结果为:

{b=2, d=4}

以上就是两个Stream流的使用实例,可以根据具体业务需求来选择不同的Stream流操作方式。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java基础之Stream流原理与用法详解 - Python技术站

(0)
上一篇 2023年5月27日
下一篇 2023年5月27日

相关文章

  • 解析Tomcat架构原理到架构设计

    解析Tomcat架构原理到架构设计 Tomcat是一个非常重要的Java Web应用服务器,它的基础架构设计对于Web应用的性能、可扩展性和稳定性有着至关重要的作用。下面我们来详细讲解如何将Tomcat架构原理解析到架构设计。 1.了解Tomcat的基本架构 Tomcat的基本架构主要由三个部分组成:Server、Service和Connector。其中,S…

    Java 2023年5月19日
    00
  • Mybatis模糊查询和动态sql语句的用法

    接下来我将详细讲解”Mybatis模糊查询和动态sql语句的用法”的完整攻略。 Mybatis模糊查询 模糊查询一般用于根据用户输入的关键字(搜索词)模糊匹配查询数据库中的数据。在Mybatis中,可以使用LIKE关键字实现模糊查询。 下面是一条简单的Mybatis模糊查询的代码示例: <select id="findUserByName&q…

    Java 2023年5月20日
    00
  • SpringBoot如何访问html和js等静态资源配置

    在Spring Boot中,我们可以使用静态资源来为我们的Web应用程序提供样式表、脚本、图像和其他静态内容。在本文中,我们将详细讲解如何在Spring Boot中访问静态资源。 静态资源目录 在Spring Boot中,我们可以将静态资源放置在以下目录中: /static /public /resources /META-INF/resources 这些目…

    Java 2023年5月18日
    00
  • Java String字符串内容实现添加双引号

    Java String 类是一个经常使用的类, 它可用于存储字符串。但有时候我们需要在字符串中添加双引号,本文将为您介绍Java中添加双引号的几种方法。 方法一:手动添加双引号 如果只需要添加一个双引号,可以直接手动在字符串两侧添加双引号,如下所示: String str = "\"Hello World!\""; S…

    Java 2023年5月26日
    00
  • MyBatis增删改查快速上手

    MyBatis增删改查快速上手 MyBatis是一款基于Java语言的ORM框架,通过XML或注解的方式操作数据库,可以实现较为灵活的数据库访问控制。本文将介绍MyBatis在增删改查方面的使用方法。 安装MyBatis MyBatis可以通过Maven依赖来引入,也可以直接下载jar包。此处以Maven方式为例,需在pom.xml文件添加以下依赖: &lt…

    Java 2023年5月19日
    00
  • log4j2的高并发死锁问题配置优化方式

    下面是关于“log4j2的高并发死锁问题配置优化方式”的完整攻略。 问题描述 在高并发场景下,log4j2可能会出现死锁问题。 这是由于log4j2的异步日志功能(Async Appenders)的工作方式导致的。Async Appenders需要将所有的日志事件都放在一个队列中,并在后台的线程中执行写入操作。但是当日志写入速度超过异步日志工作线程的处理速度…

    Java 2023年5月19日
    00
  • Java的Struts框架报错“NoSuchModuleException”的原因与解决办法

    当使用Java的Struts框架时,可能会遇到“NoSuchModuleException”错误。这个错误通常由以下原因之一起: 配置错误:如果配置文件中没有正确配置,则可能会出现此。在这种情况下,需要检查配置以解决此问题。 模块名称错误:如果模块名称不正确,则可能出现此。在这种情况下,需要检查模块名称以解决此问题。 以下是两个实例: 例 1 如果配置文件中…

    Java 2023年5月5日
    00
  • java定时任务的实现方法

    下面是针对”Java定时任务的实现方法”的详细攻略,主要介绍如何使用Java实现定时任务。 什么是定时任务? 定时任务是指在预定时期或时间,按照一定轨迹执行一些预定的操作或服务。 Java中实现定时任务的方法 1. Timer类 Java中提供了java.util.Timer类,它可以帮助我们实现简单的定时任务。 public class TimerTask…

    Java 2023年5月20日
    00
合作推广
合作推广
分享本页
返回顶部