Stream流

目录

[一,Stream 流是什么](#一,Stream 流是什么)

[二,Stream 流的作用](#二,Stream 流的作用)

[三,如何获取 Stream 对象](#三,如何获取 Stream 对象)

[四,下面是一些基本的 Stream 操作示例:](#四,下面是一些基本的 Stream 操作示例:)

终结方法:

[1.void forEach(Consumer action); 遍历流的元素](#1.void forEach(Consumer action); 遍历流的元素)

[2.Optional max(比较器); //获取流中元素的最大值,但是必须传入比较器](#2.Optional max(比较器); //获取流中元素的最大值,但是必须传入比较器)

[3.long count(); 获取流中元素的个数](#3.long count(); 获取流中元素的个数)

中间方法:

[1.Stream filter( Predicate pre );](#1.Stream filter( Predicate pre );)

[2.Stream map(Function mapper);](#2.Stream map(Function mapper);)

[3.Stream sorted(比较器); // 传入比较器排序](#3.Stream sorted(比较器); // 传入比较器排序)

[4.static Stream concat(Stream s1 , Stream s2);](#4.static Stream concat(Stream s1 , Stream s2);)

[五, Stream流的注意事项](#五, Stream流的注意事项)


一,Stream 流是什么

在Java中,Stream 是 Java 8 引入的一个重要特性,它是对集合数据进行操作的一种新的方式。使用 Stream 可以让你写出更加简洁、高效的代码。它支持各种包括过滤、映射、汇总等在内的操作,可以链式调用,使得数据处理变得更加灵活。

二,Stream 流的作用

  • 数据处理:提供了一种高效并且灵活的方式来处理数据。
  • 延迟执行 :某些操作(如 filter)不会立即执行,直到遇到终止操作(如 collectforEach)才会执行。
  • 并行操作:可以很容易地创建并行流来利用多核处理器的性能。

三,如何获取 Stream 对象

获取 Stream 对象的主要方式有以下几种:

  1. 从 Collection 获取 :任何实现了 Iterable 接口的对象都可以通过 stream() 方法来创建一个串行流,或者通过 parallelStream() 方法创建一个并行流。
  2. 数组转 Stream :可以通过 Arrays.stream(array) 方法将数组转换成 Stream。
  3. 创建无限流 :可以使用 Stream.iterate() 或者 Stream.generate() 创建无限流。
  4. 从特定类的方法中获取 :例如 Files.lines(path) 可以从文件中读取每一行生成一个 Stream。

四,下面是一些基本的 Stream 操作示例:

终结方法:

方法调用完毕后返回的不在是一个流的对象, 不能继续在使用Stream的功能

1.void forEach(Consumer<? super T> action); 遍历流的元素
java 复制代码
 list.stream().forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });
2.Optional max(比较器); //获取流中元素的最大值,但是必须传入比较器
java 复制代码
String s1 = list.stream().max((o1, o2) -> o2.length() - o1.length()).get();
3.long count(); 获取流中元素的个数
java 复制代码
long count = list.stream().count();

中间方法:

方法调用完毕后返回的依然是一个流的对象, 可以继续使用Stream的功能

1.Stream<T> filter( Predicate<T> pre );

假设有一个 List<String> 并且你想保留其中长度大于3的字符串:

java 复制代码
import java.util.Arrays;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("Tom", "Jerry", "Tuffy", "Spike");

        // 使用 filter 方法过滤长度大于3的字符串
        names.stream()
            .filter(name -> name.length() > 3)
            .forEach(System.out::println);
    }
}
2.Stream<T> map(Function<? super T, ? extends R> mapper);

假设你想将上述列表中的每个元素转换为大写:

java 复制代码
// 继续上面的例子
names.stream()
    .map(String::toUpperCase)
    .forEach(System.out::println);
3.Stream<T> sorted(比较器); // 传入比较器排序

如果你想要根据名字的长度来排序:

java 复制代码
// 继续上面的例子
names.stream()
    .sorted(Comparator.comparingInt(String::length))
    .forEach(System.out::println);
4.static Stream<T> concat(Stream<T> s1 , Stream<T> s2);
java 复制代码
ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list, "张三丰丰", "张无忌", "周芷若", "赵敏", "张强");
       Stream.concat( list.stream().filter(s -> s.startsWith("张")),list.stream().filter(s -> s.length() == 3) )
                .forEach(s-> System.out.println(s));

五, Stream流的注意事项

当使用 Java 中的 Stream API 时,有一些需要注意的事项可以帮助你更好地理解和使用它们:

  1. 惰性求值 :大部分中间操作(如 filter, map, flatMap 等)都是惰性的,它们并不会立即执行,只有在触发终端操作(如 forEach, collect, reduce 等)时,中间操作才会被执行。

  2. 管道化:一旦定义了一个流,就可以在一个表达式中链接多个操作,形成一个处理管道。这使得代码更易于阅读和维护。

  3. 不可变性:流本身是不可变的,一旦创建就不能改变其状态。所有的操作都会返回新的流。

  4. 一次性 :除非明确指定(如通过 peek),否则每个流只能被"消费"一次。一旦执行了终端操作,流就无法再次被使用。

  5. 并行流:虽然并行流可以提高执行效率,但它并不是所有场景下的最佳选择。并行流消耗更多的系统资源,并且对于涉及大量同步或阻塞操作的情况可能没有帮助。

  6. 短路行为 :一些终端操作,比如 findFirst, anyMatch, noneMatch 在满足条件时会提前终止,这种短路行为可以节省不必要的计算。

  7. 数据源类型:创建流时要考虑到数据源的类型。对于有限的数据源(如集合),可以直接创建流;而对于无限的数据源(如迭代器产生的数据),需要谨慎处理避免无限循环。

  8. 性能考虑 :尽管 Stream 提供了更简洁的语法,但在某些情况下,传统的循环可能更快。尤其是当你处理大数据集时,要评估性能影响。

  9. 异常处理:流的操作可能会抛出异常,特别是在使用自定义函数作为参数时。需要确保正确处理这些异常。

  10. 线程安全:并行流在多线程环境中运行,因此需要考虑线程安全问题,尤其是在使用共享资源时。

相关推荐
Zephyrtoria31 分钟前
区间合并:区间合并问题
java·开发语言·数据结构·算法
yuren_xia5 小时前
RabbitMQ 知识详解(Java版)
java·rabbitmq·java-rabbitmq
kfyty7256 小时前
轻量级 ioc 框架 loveqq,支持接口上传 jar 格式的 starter 启动器并支持热加载其中的 bean
java·jvm·ioc·jar·热加载
早起鸟儿6 小时前
docker-Dockerfile 配置
java·linux·运维·docker
云边小网安6 小时前
java集合篇(六) ---- ListIterator 接口
java·开发语言·青少年编程·java集合
都叫我大帅哥6 小时前
Spring WebFlux:响应式编程的“未来战士”还是“花架子”?
java·spring·flux
都叫我大帅哥6 小时前
Reactor 深度解析:响应式编程的「核反应堆」是如何工作的?
java·spring
不太厉害的程序员6 小时前
NC65配置xml找不到Bean
xml·java·后端·eclipse
我在北国不背锅7 小时前
基于Java开发的浏览器自动化Playwright-MCP服务器
java·playwright·mcp
LUCIAZZZ7 小时前
钉钉机器人-自定义卡片推送快速入门
java·jvm·spring boot·机器人·钉钉·springboot