史上最全的Java8之stream流解析和使用。

在这里插入图片描述

🏆作者简介,普修罗双战士,一直追求不断学习和成长,在技术的道路上持续探索和实践。
🏆多年互联网行业从业经验,历任核心研发工程师,项目技术负责人。
🎉欢迎 👍点赞✍评论⭐收藏

Java知识专栏学习

Java知识云集访问地址备注
Java知识(1)https://blog.csdn.net/m0_50308467/article/details/133637852Java知识专栏
Java知识(2)https://blog.csdn.net/m0_50308467/article/details/133646557Java知识专栏
Java知识(3)https://blog.csdn.net/m0_50308467/article/details/133671989Java知识专栏
Java知识(4)https://blog.csdn.net/m0_50308467/article/details/133680374Java知识专栏
Java知识(5)https://blog.csdn.net/m0_50308467/article/details/134180396Java知识专栏
Java知识(6)https://blog.csdn.net/m0_50308467/article/details/134207490Java知识专栏
Java知识(7)https://blog.csdn.net/m0_50308467/article/details/134398127Java知识专栏
Java知识(8)https://blog.csdn.net/m0_50308467/article/details/134449901Java知识专栏
Java知识(9)https://blog.csdn.net/m0_50308467/article/details/134534955Java知识专栏
Java知识(10)https://blog.csdn.net/m0_50308467/article/details/134835791Java知识专栏

文章目录

一、最全的Java8之stream流讲解和用法

在这里插入图片描述

1. 什么是Stream?

Stream是Java中的一个抽象概念,用于处理集合数据。它提供了一种函数式编程的方式来操作数据,使得代码更简洁、可读性更强。Stream可以用于对集合进行过滤、映射、排序等操作,同时还支持并行处理,提高了程序的性能。

Stream的特点包括:

1. Stream不是数据结构,它不会存储数据,而是对数据进行操作和计算。
2. Stream操作是延迟执行的,只有在真正需要结果时才会进行计算。
3. Stream可以处理大量的数据,支持并行处理,提高了程序的性能。
4. Stream提供了丰富的操作方法,可以进行过滤、映射、排序、归约等操作。

通过使用Stream,我们可以更加方便地对集合数据进行处理和操作,使得代码更加简洁、易读,并且能够充分发挥多核处理器的计算能力。

2. 为什么要使用Stream?

使用Stream可以使得代码更加简洁、易读,并且能够充分发挥多核处理器的计算能力。具体来说,Stream的优点包括:

1. 代码更加简洁:使用Stream可以将一些复杂的操作转化为一行代码,使得代码更加简洁易读。

2. 支持并行处理:Stream支持并行处理,可以充分发挥多核处理器的计算能力,提高程序的性能。

3. 延迟执行:Stream的操作是延迟执行的,只有在需要结果时才会进行计算,可以避免一些不必要的计算。

4. 丰富的操作方法:Stream提供了丰富的操作方法,可以进行过滤、映射、排序、归约等操作,可以满足各种不同的需求。

5. 支持大数据处理:Stream可以处理大量的数据,不会因为数据量过大而导致性能下降。

综上所述,使用Stream可以使得代码更加简洁易读,同时还能够提高程序的性能和支持大数据处理。

3. 使用Stream的优劣势有哪些?

使用Stream的优势包括:

1. 简洁易读:Stream提供了一种函数式编程的方式来操作数据,可以将复杂的操作转化为简洁易读的代码,提高代码的可读性和可维护性。

2. 并行处理:Stream支持并行处理,可以充分发挥多核处理器的计算能力,提高程序的性能。

3. 延迟执行:Stream的操作是延迟执行的,只有在需要结果时才会进行计算,可以避免一些不必要的计算,提高程序的效率。

4. 大数据处理:Stream可以处理大量的数据,不会因为数据量过大而导致性能下降,适用于大数据处理场景。

5. 函数式编程支持:Stream基于函数式编程的思想,可以使用Lambda表达式和方法引用等特性,使得代码更加简洁、灵活。

然而,使用Stream也存在一些劣势:

1. 学习成本:Stream的概念和使用方式相对于传统的集合操作可能需要一定的学习成本,特别是对于初学者来说。

2. 不适用于所有场景:虽然Stream提供了丰富的操作方法,但并不适用于所有的数据处理场景,有些复杂的操作可能需要使用其他方式实现。

3. 可能引发性能问题:虽然Stream支持并行处理,但在某些情况下,错误的使用并行流可能会引发性能问题,需要注意并发安全和线程安全的问题。

综上所述,使用Stream可以带来许多优势,但也需要注意其劣势,并合理选择使用Stream的场景。

4. 什么情况下使用Stream?

Stream可以在很多情况下使用,特别是在需要对集合数据进行处理和操作时。以下是一些常见的情况下使用Stream的场景:

1. 数据过滤:当需要从一个集合中筛选出符合特定条件的元素时,可以使用Stream的filter()方法进行过滤操作。

2. 数据转换:当需要对集合中的元素进行转换或映射时,可以使用Stream的map()方法进行转换操作。

3. 数据排序:当需要对集合中的元素进行排序时,可以使用Stream的sorted()方法进行排序操作。

4. 数据去重:当需要去除集合中的重复元素时,可以使用Stream的distinct()方法进行去重操作。

5. 数据归约:当需要对集合中的元素进行归约操作,如求和、求平均值等,可以使用Stream的reduce()方法进行归约操作。

6. 并行处理:当需要对大量数据进行处理,并且希望充分发挥多核处理器的计算能力时,可以使用并行流进行并行处理。

7. 链式操作:当需要对集合进行多个操作,并希望代码简洁易读时,可以使用Stream的链式操作,将多个操作连接在一起。

总之,Stream适用于需要对集合数据进行过滤、转换、排序、归约等操作的场景,特别是在需要简化代码、提高性能或处理大数据量时,使用Stream可以带来很多好处。

5. Stream 操作分类有哪些?

Stream操作可以分为中间操作(Intermediate Operations)和终端操作(Terminal Operations)两种。

1. 中间操作(Intermediate Operations):

  • filter:根据指定的条件过滤集合中的元素。
  • map:对集合中的每个元素进行映射操作,将其转换为另一种类型。
  • sorted:对集合中的元素进行排序。
  • distinct:去除集合中的重复元素。
  • limit:限制集合中元素的数量。
  • skip:跳过集合中的前几个元素。
  • peek:对集合中的每个元素执行特定操作,常用于调试和观察。

2. 终端操作(Terminal Operations):

  • forEach:对集合中的每个元素执行特定操作。
  • collect:将Stream中的元素收集到一个集合中。
  • count:计算Stream中的元素数量。
  • anyMatch:判断Stream中是否存在满足指定条件的元素。
  • allMatch:判断Stream中的所有元素是否都满足指定条件。
  • noneMatch:判断Stream中是否没有满足指定条件的元素。
  • findFirst:返回Stream中的第一个元素。
  • findAny:返回Stream中的任意一个元素。
  • min:返回Stream中的最小元素。
  • max:返回Stream中的最大元素。
  • reduce:将Stream中的元素进行归约操作,如求和、求积等。

这些操作可以根据需求进行组合使用,构建出丰富的数据处理流程。需要注意的是,终端操作会触发Stream的执行,而中间操作会延迟执行,只有在终端操作被调用时才会执行中间操作。

6. Stream的特点有哪些?生命周期?

Stream的特点有以下几个方面:

1. Stream不是数据结构:Stream并不是存储数据的数据结构,它只是对数据进行操作和计算的抽象概念。

2. 延迟执行:Stream的操作是延迟执行的,只有在终端操作被调用时才会触发中间操作的执行。这种延迟执行的特性可以提高程序的效率,避免不必要的计算。

3. 只能遍历一次:Stream只能被遍历一次,一旦遍历完成或者终端操作被调用,Stream就会关闭。如果需要再次对数据进行操作,需要重新创建一个新的Stream。

4. 支持并行处理:Stream可以支持并行处理,可以将一个Stream分成多个子任务并行执行,充分发挥多核处理器的计算能力,提高程序的性能。

Stream的生命周期包括以下几个阶段:
在这里插入图片描述
1. 创建Stream:通过不同的方式创建Stream,如集合、数组、值、生成器、迭代器等。

2. 中间操作:对Stream进行中间操作,如过滤、映射、排序、去重等。这些操作不会立即执行,而是等待终端操作的调用。

3. 终端操作:对Stream进行终端操作,如遍历、收集、计数、判断等。终端操作会触发中间操作的执行,并返回最终的结果。

4. 关闭Stream:一旦Stream被遍历完成或者终端操作被调用,Stream就会关闭,无法再进行后续的操作。

需要注意的是,Stream的生命周期是一次性的,一旦Stream被关闭,就不能再使用。如果需要对数据进行多次操作,需要创建新的Stream。同时,Stream的中间操作和终端操作可以根据需求进行组合,构建出丰富的数据处理流程。

7. Stream的创建方式有哪些?

Stream的创建方式有多种,可以通过不同的数据源来创建Stream。以下是一些常见的创建方式:

1. 通过集合创建Stream:

  • 使用 stream() 方法:可以通过集合的 stream() 方法来创建Stream。
  • 使用 parallelStream() 方法:如果需要进行并行处理,可以使用集合的 parallelStream() 方法来创建并行Stream。
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
Stream<Integer> stream = numbers.stream();
Stream<Integer> parallelStream = numbers.parallelStream();

2. 通过数组创建Stream:

  • 使用 Arrays.stream() 方法:可以通过 Arrays 类的 stream() 方法来创建Stream。
int[] array = {1, 2, 3, 4, 5};
IntStream stream = Arrays.stream(array);

3. 通过值创建Stream:

  • 使用 Stream.of() 方法:可以通过 Stream 类的 of() 方法来创建包含指定值的Stream。
Stream<String> stream = Stream.of("apple", "banana", "orange");

4. 通过生成器创建Stream:

  • 使用 Stream.generate() 方法:可以通过 Stream 类的 generate() 方法来创建一个无限序列的Stream,需要提供一个生成元素的函数。
Stream<Integer> stream = Stream.generate(() -> 1);

5. 通过迭代器创建Stream:

  • 使用 Stream.iterate() 方法:可以通过 Stream 类的 iterate() 方法来创建一个包含指定起始值和生成规则的Stream。
Stream<Integer> stream = Stream.iterate(0, n -> n + 2);

这些是常见的Stream创建方式,可以根据具体的需求选择合适的方式来创建Stream。

8. 常用经典的 Java8 Stream API 用法示例?

Stream操作可以分为中间操作(Intermediate Operations)和终端操作(Terminal Operations)两种。

中间操作(Intermediate Operations):

方法名修饰符和类型说明
mapStream map(Function<? super T, ? extends R> mapper)接收一个函数为参数,该函数应用到每个元素上,并将其映射成一个新元素(一对一)
flatMapStream flatMap(Function<? super T, ? extends Stream<? extends R>> mapper)接收一个函数为参数,该函数应用到每个元素上,并将其映射成一个新元素(一对多)
filterStream filter(Predicate<? super T> predicate)设置条件来过滤元素形成新的Stream流
distinctStream distinct()去除Stream流中重复的元素
sortedStream sorted(Comparator<? super T> comparator)指定对应的规则进行排序
peekStream peek(Consumer<? super T> action)接收一个函数为参数,用于查看该参数,但不会映射返回新元素,主要用于调试
limitStream limit(long maxSize)用于获取指定数量的流,配合skip跳过多少元素 可分页
skipStream skip(long n)用于指定跳过多少元素,配合limit使用,可分页
parallelS parallel()基于调用流,返回并行流
sequentialS sequential()基于调用流,返回串行流
unorderedS unordered()基于调用流,返回无序流
concatStream concat(Stream<? extends T> a, Stream<? extends T> b)将两个Stream流合并为新的Stream流
8.1 map:对集合中的每个元素进行映射操作,将其转换为另一种类型。

Java 8中的Stream的map()方法用于对集合中的每个元素进行映射操作,将其转换为另一种类型。它接受一个Function函数式接口作为参数,该接口定义了一个将输入元素转换为输出元素的方法。

使用map()方法的一般语法如下:

<R> Stream<R> map(Function<? super T, ? extends R> mapper)

其中,T表示Stream中的元素类型,R表示映射后的元素类型。

下面是一个示例,演示如何使用map()方法将集合中的字符串转换为大写:

List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
List<String> upperCaseNames = names.stream()
                                   .map(String::toUpperCase)
                                   .collect(Collectors.toList());
System.out.println(upperCaseNames); // 输出 [ALICE, BOB, CHARLIE]

在上面的示例中,我们首先将集合转换为Stream,然后使用map()方法传入一个方法引用(String::toUpperCase),将每个字符串转换为大写形式。最后,使用collect()方法将映射后的元素收集到一个新的List中。

通过使用map()方法,我们可以对集合中的元素进行灵活的转换操作,将其映射为另一种类型,使得代码更加简洁、可读。

8.2 flatMap:接收一个函数为参数,该函数应用到每个元素上,并将其映射成一个新元素(一对多)。

Java8中的Stream的flatMap()方法用于将一个Stream中的每个元素映射为一个新的Stream,并将这些新的Stream合并为一个单一的Stream。它接受一个Function函数式接口作为参数,该接口定义了一个用于将元素映射为Stream的方法。

使用flatMap()方法的一般语法如下:

<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper)

其中,T表示原始Stream中的元素类型,R表示映射后的新Stream中的元素类型。

下面是一个示例,演示如何使用flatMap()方法将多个集合合并为一个单一的Stream:

List<List<Integer>> numbers = Arrays.asList(
    Arrays.asList(1, 2),
    Arrays.asList(3, 4),
    Arrays.asList(5, 6)
);
List<Integer> mergedNumbers = numbers.stream()
                                     .flatMap(Collection::stream)
                                     .collect(Collectors.toList());
System.out.println(mergedNumbers); // 输出 [1, 2, 3, 4, 5, 6]

在上面的示例中,我们有一个包含多个整数集合的列表。我们将列表转换为Stream,然后使用flatMap()方法传入一个方法引用(Collection::stream),将每个集合映射为一个新的Stream。最后,我们将所有新的Stream合并为一个单一的Stream,并将其收集到一个新的列表中。

通过使用flatMap()方法,我们可以方便地将多个Stream合并为一个单一的Stream,对于扁平化处理集合的需求非常有用。

8.3 filter:根据指定的条件过滤集合中的元素。

Java 8中的Stream的filter()方法用于根据指定的条件过滤集合中的元素。它接受一个Predicate函数式接口作为参数,该接口定义了一个用于判断元素是否符合条件的方法。

使用filter()方法的一般语法如下:

Stream<T> filter(Predicate<? super T> predicate)

其中,T表示Stream中的元素类型。

下面是一个示例,演示如何使用filter()方法过滤出偶数:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> evenNumbers = numbers.stream()
                                   .filter(n -> n % 2 == 0)
                                   .collect(Collectors.toList());
System.out.println(evenNumbers); // 输出 [2, 4]

在上面的示例中,我们首先将集合转换为Stream,然后使用filter()方法传入一个Lambda表达式,判断元素是否为偶数(n % 2 == 0)。最后,使用collect()方法将过滤后的元素收集到一个新的List中。

通过使用filter()方法,我们可以根据不同的条件来过滤集合中的元素,使得代码更加简洁、可读。

8.4 sorted:对集合中的元素进行排序。

Java 8中的Stream的sorted()方法用于对集合中的元素进行排序操作。它可以按照自然顺序或者通过自定义比较器进行排序。

使用sorted()方法的一般语法如下:

Stream<T> sorted()
Stream<T> sorted(Comparator<? super T> comparator)

其中,T表示Stream中的元素类型。

下面是一个示例,演示如何使用sorted()方法对整数集合进行升序排序:

List<Integer> numbers = Arrays.asList(5, 3, 1, 4, 2);
List<Integer> sortedNumbers = numbers.stream()
                                     .sorted()
                                     .collect(Collectors.toList());
System.out.println(sortedNumbers); // 输出 [1, 2, 3, 4, 5]

在上面的示例中,我们首先将集合转换为Stream,然后使用sorted()方法对元素进行升序排序。最后,使用collect()方法将排序后的元素收集到一个新的List中。

除了使用默认的自然顺序进行排序外,我们还可以使用sorted()方法的重载版本,传入一个自定义的比较器来进行排序。例如,按照字符串长度进行排序:

List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
List<String> sortedNames = names.stream()
                                .sorted(Comparator.comparing(String::length))
                                .collect(Collectors.toList());
System.out.println(sortedNames); // 输出 [Bob, Alice, Charlie]

通过使用sorted()方法,我们可以对集合中的元素进行排序操作,使得代码更加简洁、可读。

8.5 distinct:去除集合中的重复元素。

Java 8中的Stream的distinct()方法用于去除集合中的重复元素。它会返回一个新的Stream,其中包含原始Stream中去重后的元素。

使用distinct()方法的一般语法如下:

Stream<T> distinct()

其中,T表示Stream中的元素类型。

下面是一个示例,演示如何使用distinct()方法去除整数集合中的重复元素:

List<Integer> numbers = Arrays.asList(1, 2, 2, 3, 3, 4, 5);
List<Integer> distinctNumbers = numbers.stream()
                                       .distinct()
                                       .collect(Collectors.toList());
System.out.println(distinctNumbers); // 输出 [1, 2, 3, 4, 5]

在上面的示例中,我们首先将集合转换为Stream,然后使用distinct()方法去除重复元素。最后,使用collect()方法将去重后的元素收集到一个新的List中。

通过使用distinct()方法,我们可以方便地去除集合中的重复元素,使得代码更加简洁、可读。

8.6 limit:限制集合中元素的数量。

Java 8中的Stream的limit()方法用于限制集合中元素的数量,返回一个新的Stream,其中包含前N个元素。

使用limit()方法的一般语法如下:

Stream<T> limit(long maxSize)

其中,T表示Stream中的元素类型,maxSize表示限制的元素数量。

下面是一个示例,演示如何使用limit()方法限制整数集合中的元素数量:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> limitedNumbers = numbers.stream()
                                      .limit(3)
                                      .collect(Collectors.toList());
System.out.println(limitedNumbers); // 输出 [1, 2, 3]

在上面的示例中,我们首先将集合转换为Stream,然后使用limit()方法限制只取前3个元素。最后,使用collect()方法将限制后的元素收集到一个新的List中。

通过使用limit()方法,我们可以方便地限制集合中元素的数量,使得代码更加灵活、可读。

8.7 skip:跳过集合中的前几个元素。

Java 8中的Stream的skip()方法用于跳过集合中的前N个元素,返回一个新的Stream,其中包含剩余的元素。

使用skip()方法的一般语法如下:

Stream<T> skip(long n)

其中,T表示Stream中的元素类型,n表示要跳过的元素数量。

下面是一个示例,演示如何使用skip()方法跳过整数集合中的前两个元素:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> skippedNumbers = numbers.stream()
                                       .skip(2)
                                       .collect(Collectors.toList());
System.out.println(skippedNumbers); // 输出 [3, 4, 5]

在上面的示例中,我们首先将集合转换为Stream,然后使用skip()方法跳过前两个元素。最后,使用collect()方法将剩余的元素收集到一个新的List中。

通过使用skip()方法,我们可以方便地跳过集合中的前N个元素,使得代码更加灵活、可读。

8.8 peek:对集合中的每个元素执行特定操作,常用于调试和观察。

Java 8中的Stream的peek()方法用于对集合中的每个元素执行特定操作,常用于调试和观察。它接受一个Consumer函数式接口作为参数,该接口定义了一个接受一个参数并且没有返回值的方法。

使用peek()方法的一般语法如下:

Stream<T> peek(Consumer<? super T> action)

其中,T表示Stream中的元素类型。

下面是一个示例,演示如何使用peek()方法打印集合中的每个元素:

List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
names.stream()
     .peek(System.out::println)
     .collect(Collectors.toList());

在上面的示例中,我们使用peek()方法传入一个方法引用(System.out::println),对每个元素执行打印操作。peek()方法不会改变元素本身,只是对元素进行观察或调试操作。

通过使用peek()方法,我们可以在Stream的处理过程中观察每个元素的状态,常用于调试和观察流程。

终端操作(Terminal Operations):

方法名修饰符和类型说明
forEachvoid forEach(Consumer<? super T> action)接收一个Lambda表达式,Stream流的每一个元素上执行该表达式
toArray1、Object[] toArray(); 2、<A> A[] toArray(IntFunction<A[]> generator);返回该包含该流的元素数组,可指定具体参数
reduce1、Optional reduce(BinaryOperator accumulator); 2、T reduce(T identity, BinaryOperator accumulator) 3、 U reduce(U identity,BiFunction<U, ? super T, U> accumulator,BinaryOperator combiner)把Stream流中元素组合起来并返回,sum可以理解为特殊的reduce
collect1、<R, A> R collect(Collector<? super T, A, R> collector) 2、 R collect(Supplier supplier,BiConsumer<R, ? super T> accumulator,BiConsumer<R, R> combiner)收集器,将Stream流中的元素根据接受的参数类型返回
minOptional min(Comparator<? super T> comparator)根据提供的Comparator返回此流的最小值
maxOptional max(Comparator<? super T> comparator)根据提供的Comparator返回此流的最大值
countlong count()返回流中元素数量
anyMatchboolean anyMatch(Predicate<? super T> predicate)流中存在元素符合predicate规则,则返回true
allMatchboolean allMatch(Predicate<? super T> predicate)流中全部元素符合predicate规则,则返回true
noneMatchboolean noneMatch(Predicate<? super T> predicate)流中没有元素符合predicate规则,则返回true
findFirstOptional findFirst()返回满足条件的第一个元素
findAnyOptional findAny()返回满足条件的任意元素
iteratorIterator iterator()返回迭代器
8.9 forEach:对集合中的每个元素执行特定操作。

Java 8中的Stream的forEach()方法用于对集合中的每个元素执行特定操作。它接受一个Consumer函数式接口作为参数,该接口定义了一个接受一个参数并且没有返回值的方法。

使用forEach()方法的一般语法如下:

void forEach(Consumer<? super T> action)

其中,T表示Stream中的元素类型。

下面是一个示例,演示如何使用forEach()方法打印集合中的每个元素:

List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
names.stream()
     .forEach(System.out::println);

在上面的示例中,我们使用forEach()方法传入一个方法引用(System.out::println),对每个元素执行打印操作。

通过使用forEach()方法,我们可以对Stream中的每个元素执行特定操作,如打印、保存到数据库等。注意,forEach()方法是一个终端操作,它会触发Stream的执行。

8.10 collect:将Stream中的元素收集到一个集合中。

Java 8中的Stream的collect()方法用于将Stream中的元素收集到一个结果容器中,如List、Set、Map等。它接受一个Collector参数,该参数定义了如何将元素收集到结果容器中。

使用collect()方法的一般语法如下:

<R, A> R collect(Collector<? super T, A, R> collector)

其中,T表示Stream中的元素类型,R表示最终结果的类型,A表示中间结果的类型。

下面是一个示例,演示如何使用collect()方法将整数集合收集到一个List中:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> collectedNumbers = numbers.stream()
                                        .collect(Collectors.toList());
System.out.println(collectedNumbers); // 输出 [1, 2, 3, 4, 5]

在上面的示例中,我们将集合转换为Stream,然后使用collect()方法传入Collectors.toList(),将元素收集到一个List中。

除了toList(),Java 8还提供了其他的收集器,如toSet()用于收集到Set中,toMap()用于收集到Map中等。

通过使用collect()方法,我们可以将Stream中的元素按照需求收集到不同类型的容器中,实现灵活的数据收集和处理。

8.11 count:计算Stream中的元素数量。

Java 8中的Stream的count()方法用于计算Stream中元素的数量,返回一个long类型的结果。

使用count()方法的一般语法如下:

long count()

下面是一个示例,演示如何使用count()方法计算整数集合中的元素数量:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
long count = numbers.stream()
                    .count();
System.out.println(count); // 输出 5

在上面的示例中,我们将集合转换为Stream,然后使用count()方法计算元素的数量。

通过使用count()方法,我们可以方便地获取Stream中元素的数量,对于统计和计数的需求非常有用。

8.12 anyMatch:判断Stream中是否存在满足指定条件的元素。

Java 8中的Stream的anyMatch()方法用于判断Stream中是否存在满足指定条件的元素。它接受一个Predicate函数式接口作为参数,该接口定义了一个用于判断元素是否满足条件的方法。

使用anyMatch()方法的一般语法如下:

boolean anyMatch(Predicate<? super T> predicate)

其中,T表示Stream中的元素类型。

下面是一个示例,演示如何使用anyMatch()方法判断整数集合中是否存在大于10的元素:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
boolean hasNumberGreaterThan10 = numbers.stream()
                                         .anyMatch(n -> n > 10);
System.out.println(hasNumberGreaterThan10); // 输出 false

在上面的示例中,我们将集合转换为Stream,然后使用anyMatch()方法传入一个Lambda表达式,判断元素是否大于10。最后,返回是否存在满足条件的元素。

通过使用anyMatch()方法,我们可以方便地判断Stream中是否存在满足指定条件的元素,对于判断需求非常有用。

8.13 allMatch:判断Stream中的所有元素是否都满足指定条件。

Java 8中的Stream的allMatch()方法用于判断Stream中的所有元素是否都满足指定条件。它接受一个Predicate函数式接口作为参数,该接口定义了一个用于判断元素是否满足条件的方法。

使用allMatch()方法的一般语法如下:

boolean allMatch(Predicate<? super T> predicate)

其中,T表示Stream中的元素类型。

下面是一个示例,演示如何使用allMatch()方法判断整数集合中是否所有元素都大于0:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
boolean allNumbersGreaterThanZero = numbers.stream()
                                           .allMatch(n -> n > 0);
System.out.println(allNumbersGreaterThanZero); // 输出 true

在上面的示例中,我们将集合转换为Stream,然后使用allMatch()方法传入一个Lambda表达式,判断元素是否大于0。最后,返回是否所有元素都满足条件。

通过使用allMatch()方法,我们可以方便地判断Stream中的所有元素是否都满足指定条件,对于判断需求非常有用。

8.14 noneMatch:判断Stream中是否没有满足指定条件的元素。

Java 8中的Stream的noneMatch()方法用于判断Stream中的所有元素是否都不满足指定条件。它接受一个Predicate函数式接口作为参数,该接口定义了一个用于判断元素是否不满足条件的方法。

使用noneMatch()方法的一般语法如下:

boolean noneMatch(Predicate<? super T> predicate)

其中,T表示Stream中的元素类型。

下面是一个示例,演示如何使用noneMatch()方法判断整数集合中是否所有元素都不等于10:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
boolean noneEquals10 = numbers.stream()
                              .noneMatch(n -> n == 10);
System.out.println(noneEquals10); // 输出 true

在上面的示例中,我们将集合转换为Stream,然后使用noneMatch()方法传入一个Lambda表达式,判断元素是否等于10。最后,返回是否所有元素都不满足条件。

通过使用noneMatch()方法,我们可以方便地判断Stream中的所有元素是否都不满足指定条件,对于判断需求非常有用。

8.15 findFirst:返回Stream中的第一个元素。

Java 8中的Stream的findFirst()方法用于返回Stream中的第一个元素(按照Stream的遍历顺序)。它返回一个Optional对象,表示可能存在或不存在的值。

使用findFirst()方法的一般语法如下:

Optional<T> findFirst()

其中,T表示Stream中的元素类型。

下面是一个示例,演示如何使用findFirst()方法获取整数集合中的第一个元素:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
Optional<Integer> firstNumber = numbers.stream()
                                       .findFirst();
if (firstNumber.isPresent()) {
    System.out.println(firstNumber.get()); // 输出 1
} else {
    System.out.println("No element found");
}

在上面的示例中,我们将集合转换为Stream,然后使用findFirst()方法获取第一个元素。由于集合中存在元素,因此Optional对象是存在的,我们可以使用isPresent()方法检查是否存在元素,然后使用get()方法获取元素的值。

通过使用findFirst()方法,我们可以方便地获取Stream中的第一个元素,对于需要快速获取第一个元素的需求非常有用。

8.16 findAny:返回Stream中的任意一个元素。

Java 8中的Stream的findAny()方法用于返回Stream中的任意一个元素(按照Stream的遍历顺序)。它返回一个Optional对象,表示可能存在或不存在的值。

使用findAny()方法的一般语法如下:

Optional<T> findAny()

其中,T表示Stream中的元素类型。

下面是一个示例,演示如何使用findAny()方法获取整数集合中的任意一个元素:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
Optional<Integer> anyNumber = numbers.stream()
                                     .findAny();
if (anyNumber.isPresent()) {
    System.out.println(anyNumber.get()); // 输出 1 或者其他任意一个元素
} else {
    System.out.println("No element found");
}

在上面的示例中,我们将集合转换为Stream,然后使用findAny()方法获取任意一个元素。由于集合中存在元素,因此Optional对象是存在的,我们可以使用isPresent()方法检查是否存在元素,然后使用get()方法获取元素的值。

通过使用findAny()方法,我们可以方便地获取Stream中的任意一个元素,对于不需要特定顺序的需求非常有用。

8.17 min:返回Stream中的最小元素。

Java 8中的Stream的min()方法用于找到Stream中的最小元素。它接受一个Comparator函数式接口作为参数,该接口定义了用于比较元素的方法。

使用min()方法的一般语法如下:

Optional<T> min(Comparator<? super T> comparator)

其中,T表示Stream中的元素类型。

下面是一个示例,演示如何使用min()方法找到整数集合中的最小值:

List<Integer> numbers = Arrays.asList(5, 3, 1, 4, 2);
Optional<Integer> minNumber = numbers.stream()
                                     .min(Integer::compare);
if (minNumber.isPresent()) {
    System.out.println(minNumber.get()); // 输出 1
} else {
    System.out.println("No element found");
}

在上面的示例中,我们将集合转换为Stream,然后使用min()方法传入一个方法引用(Integer::compare),用于比较元素的大小。最后,返回最小的元素。

通过使用min()方法,我们可以方便地找到Stream中的最小元素,对于寻找最小值的需求非常有用。

8.18 max:返回Stream中的最大元素。

Java 8中的Stream的max()方法用于找到Stream中的最大元素。它接受一个Comparator函数式接口作为参数,该接口定义了用于比较元素的方法。

使用max()方法的一般语法如下:

Optional<T> max(Comparator<? super T> comparator)

其中,T表示Stream中的元素类型。

下面是一个示例,演示如何使用max()方法找到整数集合中的最大值:

List<Integer> numbers = Arrays.asList(5, 3, 1, 4, 2);
Optional<Integer> maxNumber = numbers.stream()
                                     .max(Integer::compare);
if (maxNumber.isPresent()) {
    System.out.println(maxNumber.get()); // 输出 5
} else {
    System.out.println("No element found");
}

在上面的示例中,我们将集合转换为Stream,然后使用max()方法传入一个方法引用(Integer::compare),用于比较元素的大小。最后,返回最大的元素。

通过使用max()方法,我们可以方便地找到Stream中的最大元素,对于寻找最大值的需求非常有用。

8.19 reduce:将Stream中的元素进行归约操作,如求和、求积等。

Java 8中的Stream的reduce()方法用于将Stream中的元素进行归约操作,将多个元素合并为一个结果。它接受一个BinaryOperator函数式接口作为参数,该接口定义了一个用于合并两个元素的方法。

使用reduce()方法的一般语法如下:

Optional<T> reduce(BinaryOperator<T> accumulator)
T reduce(T identity, BinaryOperator<T> accumulator)

其中,T表示Stream中的元素类型。

下面是一个示例,演示如何使用reduce()方法将整数集合求和:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
Optional<Integer> sum = numbers.stream()
                               .reduce(Integer::sum);
if (sum.isPresent()) {
    System.out.println(sum.get()); // 输出 15
} else {
    System.out.println("No element found");
}

在上面的示例中,我们将集合转换为Stream,然后使用reduce()方法传入一个方法引用(Integer::sum),用于将元素进行求和操作。最后,返回求和的结果。

除了使用方法引用,reduce()方法还可以使用初始值(identity)进行归约操作。下面是一个使用初始值的示例,将整数集合求和:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
int sum = numbers.stream()
                 .reduce(0, Integer::sum);
System.out.println(sum); // 输出 15

通过使用reduce()方法,我们可以方便地对Stream中的元素进行归约操作,如求和、求积等,对于聚合操作的需求非常有用。

这些操作可以根据需求进行组合使用,构建出丰富的数据处理流程。需要注意的是,终端操作会触发Stream的执行,而中间操作会延迟执行,只有在终端操作被调用时才会执行中间操作。

collect收集器常用参数:

工厂方法返回类型说明
toCollectionCollection将Stream流中的元素收集到创建的集合中
toListList将Stream流中元素收集为List,默认为ArrayList
toSetSet将Stream流中元素收集为Set,默认为HashSet,自动去重
toMapMap<K,T>通过对应的生成器方法生成对应key和value并返回至集合中
countingLong计算Stream流中元素个数
minByOptional最小值的Optional,如果为空返回的是Optional.empty()
maxByOptional最大值的Optional,如果为空返回的是Optional.empty()
summingIntInteger求和,返回类型为Integer
summingLongLong求和,返回类型为Long
summingDoubleDouble求和,返回类型为Double
averagingIntDouble平均值,返回类型Integer
averagingLongDouble平均值,返回类型Long
averagingDoubleDouble平均值,返回类型Double
joiningString连接流中每个元素的toString方法生成的字符串
mapping指定类型先对流中的每个元素进行映射,即类型转换,然后再将新元素给定的Collector进行合并返回
groupingByMap<K,List>根据流中元素的某个值对流中的元素进行分组,并将属性值做为结果map的键
partitioningByMap<Boolean,List>将流中的元素按照给定的校验规则的结果分为两个部分,放到一个map中返回,map的键是Boolean类型,值为元素的列表List
reducing归纳返回类型与reduce方法类似
8.20 toCollection 将Stream流中的元素收集到创建的集合中

使用方法如下:

  1. 先创建一个Stream对象。可以通过集合的stream()方法创建,例如 List.stream() 或 Set.stream()。
  2. 在Stream上调用toCollection方法。
  3. 将一个Collector作为参数传递给toCollection方法。Collector是一个用于将元素收集到集合中的对象,可以使用Collectors类中提供的静态方法创建。

下面是一个示例代码:

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) {
        List<String> strings = List.of("apple", "banana", "orange");

        List<String> collected = strings.stream()
                .collect(Collectors.toCollection(ArrayList::new));

        System.out.println(collected);
    }
}

在上面的示例中,我们首先创建了一个包含一些字符串的List。然后,我们将List转换为Stream,并使用toCollection方法将Stream中的元素收集到一个ArrayList中。最后,我们打印出收集后的ArrayList对象。

输出结果为:

[apple, banana, orange]

注意:toCollection方法在Stream API中是一个终端操作,意味着一旦调用该方法后,就不能再对Stream进行其他操作。

8.21 toList 将Stream流中元素收集为List,默认为ArrayList

Java 8的Stream API中的toList方法用于将Stream中的元素收集到一个List集合中。它是Collectors类提供的一个静态方法。

使用方法如下:

  1. 先创建一个Stream对象。可以通过集合的stream()方法创建,例如 List.stream() 或 Set.stream()。
  2. 在Stream上调用toList方法。

下面是一个示例代码:

import java.util.List;
import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) {
        List<String> strings = List.of("apple", "banana", "orange");

        List<String> collected = strings.stream()
                .collect(Collectors.toList());

        System.out.println(collected);
    }
}

在上面的示例中,我们首先创建了一个包含一些字符串的List。然后,我们将List转换为Stream,并使用toList方法将Stream中的元素收集到一个List集合中。最后,我们打印出收集后的List对象。

输出结果为:

[apple, banana, orange]

toList方法在Stream API中是一个终端操作,意味着一旦调用该方法后,就不能再对Stream进行其他操作。

8.22 toSet 将Stream流中元素收集为Set,默认为HashSet,自动去重。

Java 8中的Stream流提供了toSet()方法,用于将流的元素收集到一个Set集合中。该方法的使用方法如下:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

Set<Integer> numberSet = numbers.stream()
    .collect(Collectors.toSet());

System.out.println(numberSet);

在上面的示例中,我们首先创建了一个整数列表。然后使用toSet()方法将列表中的元素收集到一个Set集合中。

运行以上代码,输出结果将会是:

[1, 2, 3, 4, 5]

这个方法可以很方便地将流的元素收集到Set集合中。

8.23 toMap<K,T> 通过对应的生成器方法生成对应key和value并返回至集合中。

Java 8中的Stream流提供了toMap()方法,用于将流的元素收集到一个Map中。该方法的使用方法如下:

List<Employee> employees = Arrays.asList(
    new Employee("John", 5000),
    new Employee("Alice", 6000),
    new Employee("Bob", 4000)
);

Map<String, Integer> employeeMap = employees.stream()
    .collect(Collectors.toMap(
        Employee::getName,
        Employee::getSalary
    ));

System.out.println(employeeMap);

在上面的示例中,我们首先创建了一个包含Employee对象的列表。然后使用toMap()方法将列表中的元素收集到一个Map中。通过传递两个函数,一个用于指定键的生成方式(这里是Employee::getName),另一个用于指定值的生成方式(这里是Employee::getSalary),我们可以将列表中的元素转换为键值对并放入Map中。

运行以上代码,输出结果将会是:

{Bob=4000, John=5000, Alice=6000}

这个方法可以很方便地将流的元素收集到Map中。

8.24 toConcurrentMap<K,T> 与toMap差不多,返回线程安全的ConcurrentHashMap。

Java 8中的Stream流提供了toConcurrentMap()方法,用于将流的元素收集到一个并发的Map中。该方法的使用方法如下:

List<String> words = Arrays.asList("hello", "world", "java");

ConcurrentMap<String, Integer> wordLengthMap = words.stream()
    .collect(Collectors.toConcurrentMap(
        word -> word,
        word -> word.length()
    ));

System.out.println(wordLengthMap);

在上面的示例中,我们首先创建了一个字符串列表。然后使用toConcurrentMap()方法将列表中的元素收集到一个并发的Map中。通过传递两个函数,一个用于指定键的生成方式(这里是word -> word),另一个用于指定值的生成方式(这里是word -> word.length()),我们可以将列表中的元素转换为键值对并放入Map中。

运行以上代码,输出结果将会是:

{world=5, java=4, hello=5}

这个方法可以很方便地将流的元素收集到并发的Map中。

8.25 counting 计算Stream流中元素个数。

Java 8中的Stream流提供了counting()方法,用于统计流中元素的个数。该方法的使用方法如下:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

long count = numbers.stream()
    .filter(n -> n > 2)
    .count();

System.out.println("Count: " + count);

在上面的示例中,我们首先创建了一个整数列表。然后使用counting()方法统计满足条件(大于2)的元素个数。通过调用count()方法,我们可以获取统计结果。

运行以上代码,输出结果将会是:

Count: 3

这个方法可以很方便地统计流中元素的个数。

8.26 minBy 最小值的Optional,如果为空返回的是Optional.empty()。

Java 8中的Stream流提供了minBy()方法,用于在流中找到最小的元素。该方法的使用方法如下:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

Optional<Integer> min = numbers.stream()
    .min(Integer::compareTo);

if (min.isPresent()) {
    System.out.println("Min: " + min.get());
} else {
    System.out.println("Stream is empty!");
}

在上面的示例中,我们首先创建了一个整数列表。然后使用minBy()方法找到列表中的最小元素。通过传递一个比较函数(这里是Integer::compareTo),可以确定最小元素的顺序。

minBy()方法返回一个Optional对象,因为流可能为空。我们可以使用isPresent()方法检查Optional对象是否有值,然后使用get()方法获取最小值。

运行以上代码,输出结果将会是:

Min: 1

这个方法可以很方便地在流中找到最小的元素。

8.27 maxBy 最大值的Optional,如果为空返回的是Optional.empty()。

Java 8中的Stream流提供了maxBy()方法,用于在流中找到最大的元素。该方法的使用方法如下:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

Optional<Integer> max = numbers.stream()
    .max(Integer::compareTo);

if (max.isPresent()) {
    System.out.println("Max: " + max.get());
} else {
    System.out.println("Stream is empty!");
}

在上面的示例中,我们首先创建了一个整数列表。然后使用maxBy()方法找到列表中的最大元素。通过传递一个比较函数(这里是Integer::compareTo),可以确定最大元素的顺序。

maxBy()方法返回一个Optional对象,因为流可能为空。我们可以使用isPresent()方法检查Optional对象是否有值,然后使用get()方法获取最大值。

运行以上代码,输出结果将会是:

Max: 5

这个方法可以很方便地在流中找到最大的元素。

8.28 summingInt 求和,返回类型为Integer。

Java 8中的Stream流提供了summingInt()方法,用于对流中的元素进行Int类型的求和操作。该方法的使用方法如下:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

int sum = numbers.stream()
    .collect(Collectors.summingInt(Integer::intValue));

System.out.println("Sum: " + sum);

在上面的示例中,我们首先创建了一个整数列表。然后使用summingInt()方法对列表中的元素进行求和操作。通过传递一个函数(这里是Integer::intValue),将整数转换为int值,然后进行求和计算。

运行以上代码,输出结果将会是:

Sum: 15

这个方法可以很方便地对流中的元素进行求和操作。

8.29 summingLong 求和,返回类型为Long。

Java 8中的Stream流提供了summingLong()方法,用于对流中的元素进行Long类型的求和操作。该方法的使用方法如下:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

long sum = numbers.stream()
    .collect(Collectors.summingLong(Integer::longValue));

System.out.println("Sum: " + sum);

在上面的示例中,我们首先创建了一个整数列表。然后使用summingLong()方法对列表中的元素进行求和操作。通过传递一个函数(这里是Integer::longValue),将整数转换为Long类型,然后进行求和计算。

运行以上代码,输出结果将会是:

Sum: 15

这个方法可以很方便地对流中的元素进行求和操作。

8.30 summingDouble 求和,返回类型为Double。

Java 8中的Stream流提供了summingDouble()方法,用于对流中的元素进行Double类型的求和操作。该方法的使用方法如下:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

double sum = numbers.stream()
    .collect(Collectors.summingDouble(Integer::doubleValue));

System.out.println("Sum: " + sum);

在上面的示例中,我们首先创建了一个整数列表。然后使用summingDouble()方法对列表中的元素进行求和操作。通过传递一个函数(这里是Integer::doubleValue),将整数转换为Double类型,然后进行求和计算。

运行以上代码,输出结果将会是:

Sum: 15.0

这个方法可以很方便地对流中的元素进行求和操作。

8.31 averagingInt 平均值,返回类型Integer。

Java 8中的Stream流提供了averagingInt()方法,用于计算流中元素的平均值(Int类型)。该方法的使用方法如下:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

double average = numbers.stream()
    .collect(Collectors.averagingInt(Integer::intValue));

System.out.println("Average: " + average);

在上面的示例中,我们首先创建了一个整数列表。然后使用averagingInt()方法计算列表中元素的平均值。通过传递一个函数(这里是Integer::intValue),将整数转换为int值,然后进行平均计算。

运行以上代码,输出结果将会是:

Average: 3.0

这个方法可以很方便地计算流中元素的平均值。

8.32 averagingLong 平均值,返回类型Long。

Java 8中的Stream流提供了averagingLong()方法,用于计算流中元素的平均值(Long类型)。该方法的使用方法如下:

List<Long> numbers = Arrays.asList(1L, 2L, 3L, 4L, 5L);

double average = numbers.stream()
    .collect(Collectors.averagingLong(Long::longValue));

System.out.println("Average: " + average);

在上面的示例中,我们首先创建了一个Long类型的列表。然后使用averagingLong()方法计算列表中元素的平均值。通过传递一个函数(这里是Long::longValue),将Long类型转换为long值,然后进行平均计算。

运行以上代码,输出结果将会是:

Average: 3.0

这个方法可以很方便地计算流中元素的平均值。

8.33 averagingDouble 平均值,返回类型Double。

Java 8中的Stream流提供了averagingDouble()方法,用于计算流中元素的平均值(Double类型)。该方法的使用方法如下:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

double average = numbers.stream()
    .collect(Collectors.averagingDouble(Integer::doubleValue));

System.out.println("Average: " + average);

在上面的示例中,我们首先创建了一个整数列表。然后使用averagingDouble()方法计算列表中元素的平均值。通过传递一个函数(这里是Integer::doubleValue),将整数转换为Double类型,然后进行平均计算。

运行以上代码,输出结果将会是:

Average: 3.0

这个方法可以很方便地计算流中元素的平均值。

8.34 summarizingInt 汇总,返回包含元素个数、最大值、最小值、求和值、平均值,值类型为Integer。

Java 8中的Stream流提供了summarizingInt()方法,用于对流中的元素进行Int类型的汇总统计。该方法的使用方法如下:

List<Employee> employees = Arrays.asList(
    new Employee("John", 5000),
    new Employee("Alice", 6000),
    new Employee("Bob", 4000)
);

IntSummaryStatistics stats = employees.stream()
    .collect(Collectors.summarizingInt(Employee::getSalary));

System.out.println("Count: " + stats.getCount());
System.out.println("Sum: " + stats.getSum());
System.out.println("Average: " + stats.getAverage());
System.out.println("Max: " + stats.getMax());
System.out.println("Min: " + stats.getMin());

在上面的示例中,我们首先创建了一个包含Employee对象的列表。然后使用summarizingInt()方法对Employee对象的薪水进行汇总统计。通过调用getCount()、getSum()、getAverage()、getMax()和getMin()等方法,我们可以获取统计结果的各个属性。

运行以上代码,输出结果将会是:

Count: 3
Sum: 15000
Average: 5000.0
Max: 6000
Min: 4000

这些统计结果可以帮助我们对数据进行分析和总结。

8.35 summarizingLong 汇总,返回包含元素个数、最大值、最小值、求和值、平均值,值类型为Long。

Java 8中的Stream流提供了summarizingLong()方法,用于对流中的元素进行Long类型的汇总统计。该方法的使用方法如下:

List<Employee> employees = Arrays.asList(
    new Employee("John", 5000),
    new Employee("Alice", 6000),
    new Employee("Bob", 4000)
);

LongSummaryStatistics stats = employees.stream()
    .collect(Collectors.summarizingLong(Employee::getSalary));

System.out.println("Count: " + stats.getCount());
System.out.println("Sum: " + stats.getSum());
System.out.println("Average: " + stats.getAverage());
System.out.println("Max: " + stats.getMax());
System.out.println("Min: " + stats.getMin());

在上面的示例中,我们首先创建了一个包含Employee对象的列表。然后使用summarizingLong()方法对Employee对象的薪水进行汇总统计。通过调用getCount()、getSum()、getAverage()、getMax()和getMin()等方法,我们可以获取统计结果的各个属性。

运行以上代码,输出结果将会是:

Count: 3
Sum: 15000
Average: 5000.0
Max: 6000
Min: 4000

这些统计结果可以帮助我们对数据进行分析和总结。

8.36 summarizingDouble 汇总,返回包含元素个数、最大值、最小值、求和值、平均值,值类型为Double。

Java 8中的Stream流提供了summarizingDouble()方法,用于对流中的元素进行Double类型的汇总统计。该方法的使用方法如下:

List<Employee> employees = Arrays.asList(
    new Employee("John", 5000.0),
    new Employee("Alice", 6000.0),
    new Employee("Bob", 4000.0)
);

DoubleSummaryStatistics stats = employees.stream()
    .collect(Collectors.summarizingDouble(Employee::getSalary));

System.out.println("Count: " + stats.getCount());
System.out.println("Sum: " + stats.getSum());
System.out.println("Average: " + stats.getAverage());
System.out.println("Max: " + stats.getMax());
System.out.println("Min: " + stats.getMin());

在上面的示例中,我们首先创建了一个包含Employee对象的列表。然后使用summarizingDouble()方法对Employee对象的薪水进行汇总统计。通过调用getCount()、getSum()、getAverage()、getMax()和getMin()等方法,我们可以获取统计结果的各个属性。

运行以上代码,输出结果将会是:

Count: 3
Sum: 15000.0
Average: 5000.0
Max: 6000.0
Min: 4000.0

这些统计结果可以帮助我们对数据进行分析和总结。

8.37 joining 连接流中每个元素的toString方法生成的字符串。

Java 8中的Stream流提供了joining()方法,用于将流中的元素连接为一个字符串。该方法的使用方法如下:

List<String> words = Arrays.asList("Hello", "World", "Java");
String result = words.stream()
    .collect(Collectors.joining(", "));
System.out.println(result);

在上面的示例中,我们首先创建了一个字符串列表,然后使用joining()方法将列表中的元素连接为一个字符串。在joining()方法中,我们可以指定连接字符串的分隔符(这里是", ")。

运行以上代码,输出结果为:“Hello, World, Java”。

joining()方法还可以接受其他参数,例如前缀、后缀等,以满足更多的连接需求。你可以根据具体的需求使用不同的方法重载。

8.38 mapping 指定类型先对流中的每个元素进行映射,即类型转换,然后再将新元素给定的Collector进行合并返回。

Java 8中的Stream流提供了mapping()方法,用于对流中的元素进行映射操作。该方法的使用方法如下:

List<String> words = Arrays.asList("Java", "Stream", "API");
List<Integer> wordLengths = words.stream()
    .map(String::length)
    .collect(Collectors.toList());

在上面的示例中,我们首先创建了一个字符串列表,然后使用mapping()方法将列表中的每个字符串映射为其长度。最后,我们使用toList()方法将映射结果收集到一个List集合中。

mapping()方法需要一个函数作为参数,该函数用于将流中的元素映射为另一种类型。在上面的示例中,我们使用String::length方法将字符串映射为它们的长度。

8.39 collectingAndThen 转换函数返回的类型转换结束后,对其结果再进行处理返回。

Java 8中的Stream流提供了collectingAndThen()方法,用于在收集元素之后执行一个转换操作。该方法的使用方法如下:

List<Integer> numbers = Stream.of(1, 2, 3, 4, 5)
    .collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList));

在上面的示例中,我们首先使用toList()方法将整数流收集到一个List集合中,然后通过collectingAndThen()方法将这个List集合转换为一个不可修改的List集合。在collectingAndThen()方法中,我们传递两个参数,第一个参数是用于收集元素的收集器(这里是toList()),第二个参数是一个函数,用于对收集结果进行转换(这里是将List转换为不可修改的List)。

collectingAndThen()方法的作用是在收集元素之后执行一些额外的操作,例如对收集结果进行转换、添加额外的处理逻辑等。

8.40 groupingByMap<K,List> 根据流中元素的某个值对流中的元素进行分组,并将属性值做为结果map的键。

Java 8的Stream API中的groupingBy方法是一个非常有用的方法,它可以将 Stream 中的元素根据某个属性分组,返回一个 Map 对象,其中每个键都是分组属性值,每个值则是该属性值对应的元素集合。该方法有两个重载形式,其中之一是 groupingBy(Function<? super T, ? extends K> classifier),即以元素的某个属性值为键进行分组。

使用方法如下:

  1. 先创建一个Stream对象。可以通过集合的stream()方法创建,例如 List.stream() 或 Set.stream()。
  2. 在Stream上调用groupingBy方法,并传递一个分组函数,该函数用于将元素映射为分组键。
  3. 如果需要,在groupingBy方法后面可以继续调用其他Stream操作,如过滤、映射等。

下面是一个示例代码:

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) {
        List<String> words = Arrays.asList("apple", "banana", "avocado", "peach", "pear", "pineapple");

        Map<Character, List<String>> groups = words.stream()
                .collect(Collectors.groupingBy(word -> word.charAt(0)));

        System.out.println(groups);
    }
}

在上面的示例中,我们首先创建了一个包含一些字符串的List。然后,我们将List转换为Stream,并使用groupingBy方法对元素进行分组,分组条件是字符串的第一个字母。最后,我们打印出分组结果。

输出结果为:

{a=[apple, avocado], b=[banana], p=[peach, pear, pineapple]}

注意: groupingBy方法返回一个Map对象,其中键是分组条件(即groupingBy传入的参数),值是对应的元素列表。分组键可以是任意类型。

8.41 groupingByConcurrent 与groupingBy类似,返回ConcurrentHashMap。

Java 8中的Stream流提供了groupingByConcurrent()方法,用于根据指定的分类条件对流中的元素进行并发分组。该方法的使用方法如下:

List<String> words = Arrays.asList("apple", "banana", "cat", "dog", "elephant");

ConcurrentMap<Integer, List<String>> wordGroups = words.stream()
    .collect(Collectors.groupingByConcurrent(String::length));

System.out.println(wordGroups);

在上面的示例中,我们首先创建了一个字符串列表。然后使用groupingByConcurrent()方法根据字符串的长度对列表中的元素进行并发分组。最终,我们得到一个ConcurrentMap,其中键是字符串的长度,值是具有相同长度的字符串列表。

运行以上代码,输出结果将会是:

{3=[cat, dog], 5=[apple], 6=[banana], 8=[elephant]}

这个方法可以很方便地将流中的元素根据指定的分类条件进行并发分组。

8.42 partitioningBy 将流中的元素按照给定的校验规则的结果分为两个部分,放到一个map中返回,map的键是Boolean类型,值为元素的列表List。

Java 8中的Stream流提供了partitioningBy()方法,用于根据指定的条件将流中的元素进行分区。该方法的使用方法如下:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

Map<Boolean, List<Integer>> evenOddMap = numbers.stream()
    .collect(Collectors.partitioningBy(num -> num % 2 == 0));

List<Integer> evenNumbers = evenOddMap.get(true);
List<Integer> oddNumbers = evenOddMap.get(false);

System.out.println("Even numbers: " + evenNumbers);
System.out.println("Odd numbers: " + oddNumbers);

在上面的示例中,我们首先创建了一个整数列表。然后使用partitioningBy()方法根据元素是否为偶数进行分区。最终,我们得到一个Map,其中键为true代表偶数,键为false代表奇数,对应的值是相应的元素列表。

运行以上代码,输出结果将会是:

Even numbers: [2, 4, 6, 8, 10]
Odd numbers: [1, 3, 5, 7, 9]

这个方法可以很方便地将流中的元素根据指定的条件进行分区。

8.43 reducing 归纳返回类型与reduce方法类似。

Java 8中的Stream流提供了reducing()方法,用于将流中的元素按照指定的操作进行归约。该方法的使用方法如下:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

int sum = numbers.stream()
    .reduce(0, (a, b) -> a + b);

System.out.println("Sum: " + sum);

在上面的示例中,我们首先创建了一个整数列表。然后使用reducing()方法对列表中的元素进行求和操作。通过传递一个初始值和一个二元操作(这里是lambda表达式),将流中的元素进行累加。

运行以上代码,输出结果将会是:

Sum: 15

这个方法可以很方便地对流中的元素进行归约操作,例如求和、求积、求最大值等。

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值