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

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日

相关文章

  • Java实现的生成二维码统计扫描次数并转发到某个地址功能详解

    Java实现的生成二维码统计扫描次数并转发到某个地址功能详解 简介 二维码是一种可被扫描识别的矩阵条形码。在现代生活中,二维码广泛应用于各种场景中,例如商业推广、门禁系统、实名认证、票务管理等等。Java语言可以用来生成二维码,并通过统计扫描次数等功能对二维码进行管理。 实现步骤 以下是使用Java生成二维码并统计扫描次数并转发到某个地址的具体步骤: 步骤一…

    Java 2023年5月20日
    00
  • Java String字符串和Unicode字符相互转换代码详解

    Java String字符串和Unicode字符相互转换代码详解 什么是Unicode Unicode是一种字符编码方案,它为每个字符分配了一个唯一的编号,方便不同的计算机系统之间进行字符编码的统一。 在Java中,字符型变量是16位的Unicode字符。 Unicode字符转换为Java String字符串 我们可以通过Java语言中的String类型的构…

    Java 2023年5月26日
    00
  • java高级用法之绑定CPU的线程Thread Affinity简介

    Java高级用法之绑定CPU的线程Thread Affinity简介 什么是Thread Affinity? Thread Affinity(线程亲和性)是指将一个线程绑定到一个指定的 CPU 上面,使得线程只在这个特定的 CPU 上运行。在高性能计算和计算机游戏等领域,Thread Affinity 被广泛使用,以提高应用的执行效率。 Thread Aff…

    Java 2023年5月19日
    00
  • java线程池实现批量下载文件

    关于Java线程池实现批量下载文件,可以按照以下步骤进行: 1. 创建线程池 首先需要使用 Executors.newFixedThreadPool() 方法创建一个固定大小的线程池,例如: private static int THREAD_COUNT = 5; // 线程池大小 private static ExecutorService executo…

    Java 2023年5月19日
    00
  • 简单谈谈Struts动态表单(DynamicForm)

    简单谈谈Struts动态表单(DynamicForm) 在Struts 1.x中,有一个叫做DynamicForm的类,其主要作用是用来封装动态生成的表单数据的。通过使用DynamicForm,开发者可以更方便地处理多个表单元素、动态表单元素等情况,使编写表单逻辑更加简单易行。 动态表单介绍 DynamicForm的基本用法是在Struts配置文件中定义Ac…

    Java 2023年5月20日
    00
  • 麻雀虽小五脏俱全 Dojo自定义控件应用

    麻雀虽小五脏俱全 Dojo自定义控件应用是指采用Dojo技术栈自定义开发控件实现特定功能的过程。在这个过程中,我们使用Dojo提供的模块、函数、接口等来编写自己的控件,可以根据需求自由组合、扩展,从而实现功能丰富、灵活可定制的应用程序。下面是 Dojo 自定义控件应用的详细攻略: 1. 安装 Dojo 工具包 在使用 Dojo 进行开发之前,需要先安装 Do…

    Java 2023年6月15日
    00
  • 初学java常用开发工具介绍

    初学Java常用开发工具介绍 Java是一门广受欢迎的编程语言,它在企业级应用开发中也有比较广泛的应用。针对初学者来说,选择一个适合自己的开发工具,能够大大提高编写程序的效率。本文将介绍初学Java常用的开发工具列表和使用方法。 一、常用开发工具列表 1. Eclipse Eclipse 是一个全功能开发平台,支持Java开发以及多种其他编程语言。它是一个基…

    Java 2023年6月15日
    00
  • AOP之事务管理的两种配置方式

    对于AOP之事务管理的两种配置方式,我们可以使用以下两种方式进行配置: 一、使用标签配置事务管理 1. 在XML配置文件中声明TransactionManager代理 <!– 声明 TransactionManager bean –> <bean id="txManager" class="org.spri…

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