珠海市网站建设公司,php网站授权,网站模块划分规划,深圳外贸公司前十名#x1f3f7;️个人主页#xff1a;牵着猫散步的鼠鼠 #x1f3f7;️系列专栏#xff1a;Java全栈-专栏 #x1f3f7;️个人学习笔记#xff0c;若有缺误#xff0c;欢迎评论区指正 前些天发现了一个巨牛的人工智能学习网站#xff0c;通俗易懂#xff0c;风趣幽默️个人主页牵着猫散步的鼠鼠 ️系列专栏Java全栈-专栏 ️个人学习笔记若有缺误欢迎评论区指正 前些天发现了一个巨牛的人工智能学习网站通俗易懂风趣幽默忍不住分享一下给大家。点击跳转到网站AI学习网站。 目录
前言
Stream API的三个阶段
创建Stream流
Stream API中间操作
filter
map
flatMap
distinct
sorted
peek
limit 和 skip
Stream API终端操作
forEach
toArray
reduce
collect
count
anyMatch、allMatch 和 noneMatch
findAny 和 findFirst
min 和 max
注意事项
总结 前言
Java8中有两大最为重要的改变。第一个是 Lambda 表达式另外一个则是 Stream API。
Stream 是 Java8 中处理集合的关键抽象概念它可以指定你希望对集合进行的操作可以执行非常复杂的查找、过滤和映射数据等操作。使用Stream API 对集合数据进行操作就类似于使用 SQL 执行的数据库查询。也可以使用 Stream API 来并行执行操作。简而言之Stream API 提供了一种高效且易于使用的处理数据的方式 流是数据渠道用于操作数据源集合、数组等所生成的元素序列。“集合讲的是数据流讲的是计算” 注意
① Stream 自己不会存储元素。
② Stream 不会改变源对象。相反他们会返回一个持有结果的新Stream。
③ Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行。 Stream API的三个阶段
在Java中Stream 是Java 8引入的一个新概念用于处理集合Collections数据的一种抽象。Java的Stream API 提供了一种声明式的方式来操作数据集合可以用更简洁、可读性更强的代码来进行集合的操作。
Java Stream API的操作可以分为三个阶段
1. 创建流Creation of Stream 这个阶段涉及到从不同的数据源创建流可以是集合、数组、I/O通道等。
ListInteger numbers Arrays.asList(1, 2, 3, 4, 5);
StreamInteger stream numbers.stream();2. 中间操作Intermediate Operations 这个阶段包括对流的转换操作可以对流进行过滤、映射、排序等操作。这些操作并不会改变原始数据源而是返回一个新的流。
StreamInteger filteredStream stream.filter(x - x 2);3. 终端操作Terminal Operations 这个阶段是对流进行最终操作触发流的遍历可以产生一个结果或者副作用。终端操作是流的最后一个操作执行后流将不可再用。
long count filteredStream.count();这三个阶段的设计使得可以通过链式调用的方式组合多个操作从而编写更为清晰和简洁的代码。这种方式也有助于提高代码的可读性和可维护性。
当然这里只是对于Stream API三个阶段的概述只是告诉大家简单分为三个阶段至于三个阶段里面有哪些主要的方法我们在下文进行详细叙述这里我们点到为止现在大家心里面就应该有这么一个蓝图或者是基本框架知道我们接下来将会沿着那个几个方向展开叙述
创建Stream流
在Java中你可以使用多种方式来创建Stream流。
从集合创建
使用集合类的 stream() 或 parallelStream() 方法可以创建对应的流。例如
ListString list Arrays.asList(apple, banana, orange);
StreamString streamFromList list.stream();从数组创建
使用 Arrays.stream() 方法可以从数组中创建流
String[] array {apple, banana, orange};
StreamString streamFromArray Arrays.stream(array);通过Stream的静态方法创建
Stream 类提供了静态方法 of()可以传入一系列元素来创建流
StreamString stream Stream.of(apple, banana, orange);使用Stream的generate和iterate方法
Stream 类还提供了 generate 和 iterate 方法用于生成无限流
// 生成包含随机整数的无限流
StreamInteger infiniteStream Stream.generate(() - (int) (Math.random() * 100));// 从指定的起始值开始按照某个规则生成无限流
StreamInteger sequentialStream Stream.iterate(1, n - n 1);通过文件生成流
java.nio.file.Files 类提供了静态方法 lines()可以用来读取文件内容并生成流
Path path Paths.get(example.txt);
StreamString fileLines Files.lines(path);使用正则表达式生成流
Pattern 类的 splitAsStream 方法可以根据正则表达式将字符串分割成流
String text apple,orange,banana;
StreamString textStream Pattern.compile(,).splitAsStream(text);Stream API中间操作
Stream API 提供了许多中间操作用于对流进行转换、筛选和处理。
filter
用于筛选元素根据指定的条件保留符合条件的元素。
ListInteger numbers Arrays.asList(1, 2, 3, 4, 5);
StreamInteger filteredStream numbers.stream().filter(x - x 2);map
对流中的每个元素应用指定的函数并将结果映射为一个新的元素。
ListString words Arrays.asList(apple, banana, orange);
StreamInteger wordLengths words.stream().map(String::length);flatMap
将流中的每个元素都转换为一个流然后将这些流连接起来成为一个流。
ListListInteger numbers Arrays.asList(Arrays.asList(1, 2),Arrays.asList(3, 4),Arrays.asList(5, 6)
);StreamInteger flatStream numbers.stream().flatMap(List::stream);distinct
去除流中的重复元素。
ListInteger numbers Arrays.asList(1, 2, 2, 3, 4, 4, 5);
StreamInteger distinctNumbers numbers.stream().distinct();sorted
对流中的元素进行排序。
ListInteger numbers Arrays.asList(3, 1, 4, 1, 5, 9, 2, 6);
StreamInteger sortedNumbers numbers.stream().sorted();peek
对流中的每个元素执行操作主要用于调试和观察流中的元素。
ListString words Arrays.asList(apple, banana, orange);
StreamString peekStream words.stream().peek(System.out::println);limit 和 skip
limit 用于截断流保留指定数量的元素而 skip 则用于跳过指定数量的元素。
ListInteger numbers Arrays.asList(1, 2, 3, 4, 5);
StreamInteger limitedStream numbers.stream().limit(3);
StreamInteger skippedStream numbers.stream().skip(2);Stream API终端操作
Stream API 的终端操作用于触发对流的最终操作产生结果或者引起副作用。
forEach
对流中的每个元素执行指定的操作。
ListString words Arrays.asList(apple, banana, orange);
words.stream().forEach(System.out::println);toArray
将流中的元素转换为数组。
ListString words Arrays.asList(apple, banana, orange);
String[] wordArray words.stream().toArray(String[]::new);reduce
对流中的元素进行归约操作可以用于求和、求最大值、最小值等。
ListInteger numbers Arrays.asList(1, 2, 3, 4, 5);
OptionalInteger sum numbers.stream().reduce(Integer::sum);collect
将流中的元素收集到一个集合中例如 List、Set 或 Map。
ListString words Arrays.asList(apple, banana, orange);
ListString collectedWords words.stream().collect(Collectors.toList());count
返回流中的元素数量。
ListInteger numbers Arrays.asList(1, 2, 3, 4, 5);
long count numbers.stream().count();anyMatch、allMatch 和 noneMatch
用于检查流中是否存在满足指定条件的元素。
ListInteger numbers Arrays.asList(1, 2, 3, 4, 5);
boolean anyGreaterThanThree numbers.stream().anyMatch(x - x 3);
boolean allGreaterThanTwo numbers.stream().allMatch(x - x 2);
boolean noneGreaterThanFive numbers.stream().noneMatch(x - x 5);findAny 和 findFirst
返回流中的任意一个元素或者第一个元素。
ListString words Arrays.asList(apple, banana, orange);
OptionalString anyWord words.stream().findAny();
OptionalString firstWord words.stream().findFirst();min 和 max
返回流中的最小值或最大值。
ListInteger numbers Arrays.asList(3, 1, 4, 1, 5, 9, 2, 6);
OptionalInteger minNumber numbers.stream().min(Integer::compare);
OptionalInteger maxNumber numbers.stream().max(Integer::compare);注意事项
使用Stream API时有一些需要注意的重要事项以确保正确、高效地利用这一功能
只能使用一次 一个 Stream 实例只能被消费执行终端操作一次。如果你尝试对已经使用过的流进行其他终端操作会抛出 IllegalStateException 异常。如果需要再次操作可以重新创建一个新的流。
ListString words Arrays.asList(apple, banana, orange);
StreamString wordStream words.stream();// 正确的做法
long count wordStream.count();// 错误的做法会抛出IllegalStateException
long anotherCount wordStream.count();及早退出 在处理大量数据时及早退出可以提高性能。使用 anyMatch()、findFirst() 等终端操作时一旦找到符合条件的元素就会立即返回不再继续处理后续元素。
ListInteger numbers Arrays.asList(1, 2, 3, 4, 5);
boolean anyGreaterThanThree numbers.stream().anyMatch(x - {System.out.println(Checking: x);return x 3;
});并行流的谨慎使用 Stream API 提供了并行流的支持可以通过 parallel() 方法将顺序流转换为并行流。但并不是所有的场景都适合使用并行流因为在某些情况下并行流可能会导致性能下降甚至出现并发问题。在并行流的使用上需要注意线程安全等问题。
ListInteger numbers Arrays.asList(1, 2, 3, 4, 5);
long count numbers.parallelStream().filter(x - x 2).count();使用适当的数据结构 在创建流时选择适当的数据结构能够影响流操作的性能。例如ArrayList 在顺序访问时性能较好而 LinkedList 在随机访问时性能较好。
总结
总体而言了解Stream API的使用原则结合具体的业务场景和性能需求能够更好地利用Stream API完成任务。注意流的延迟计算特性避免副作用可以使代码更加清晰、可读并提高代码的可维护性。