gpt4 book ai didi

[Java]Stream流使用最多的方式

转载 作者:撒哈拉 更新时间:2024-12-12 00:27:25 57 4
gpt4 key购买 nike

Java 中 Stream 流的用法全解析


在 Java 编程中,Stream 流提供了一种高效、便捷的方式来处理集合数据。它可以让我们以声明式的方式对数据进行各种操作,如过滤、映射、排序、聚合等,大大简化了数据处理的代码编写。本文将详细介绍 Java 中 Stream 流的用法,包括基础用法、中级用法、高级用法以及一些特殊方法的使用。

1、基础用法

1. 创建 Stream


  • 从集合创建 Stream:通过调用集合的 stream() 方法可以创建一个顺序流。例如:
List<String> list = Arrays.asList("apple", "banana", "cherry");
Stream<String> stream1 = list.stream();
  • 从数组创建 Stream:使用 Arrays.stream() 方法可以从数组创建流。例如:
String[] array = {"apple", "banana", "cherry"};
Stream<String> stream2 = Arrays.stream(array);

2. 中间操作

  。

  • filter:过滤元素:使用 filter 方法可以根据指定的条件过滤流中的元素。例如,以下代码过滤出以 "a" 开头的字符串:
list.stream()
  .filter(s -> s.startsWith("a"))
  .forEach(System.out::println); // 输出: apple
  • map:转换元素map 方法可以将流中的每个元素按照指定的函数进行转换。例如,将字符串转换为大写:
list.stream()
  .map(String::toUpperCase)
  .forEach(System.out::println); // 输出: APPLE BANANA CHERRY

3. 终止操作

  。

  • forEach:遍历元素forEach 方法用于遍历流中的每个元素并执行指定的操作。例如:
list.stream().forEach(System.out::println);

  。

  • collect:收集结果到集合collect 方法可以将流中的元素收集到指定的集合中。例如,收集长度大于 5 的字符串到一个新的列表中:
List<String> result1 = list.stream()
  .filter(s -> s.length() > 5)
  .collect(Collectors.toList());

// 或者使用 toList() 方法(Java 16 及以上版本)
List<String> result2 = list.stream()
  .filter(s -> s.length() > 5)
  .toList();

2、中级用法

1. 排序

  。

  • sorted:自然排序或自定义排序sorted 方法可以对流中的元素进行排序。如果元素实现了 Comparable 接口,可以直接使用无参的 sorted 方法进行自然排序。例如:
list.stream()
  .sorted()
  .forEach(System.out::println); // 输出: apple banana cherry

如果需要自定义排序规则,可以传入一个 Comparator 比较器。例如,按照字符串长度倒序排序:

list.stream()
  .sorted(Comparator.reverseOrder())
  .forEach(System.out::println); // 输出: cherry banana apple

2. 去重

  。

使用  distinct 方法可以去除流中的重复元素。例如:
List<Integer> numbers = Arrays.asList(1, 2, 2, 3, 4, 4, 5);
List<Integer> distinctNumbers = numbers.stream()
  .distinct()
  .toList();

3. 聚合操作

  。

  • reduce:归约操作reduce 方法可以对流中的元素进行归约操作,例如求和、求乘积等。例如,计算整数列表的总和:
Optional<Integer> sum = numbers.stream()
  .reduce((a, b) -> a + b); // 可替换为.reduce(Integer::sum);
System.out.println(sum.get()); // 输出: 19

3、高级用法

1. 并行流

  。

  • parallelStream:并行处理(提高效率):使用 parallelStream 方法可以创建一个并行流,它会在多个线程上并行处理流中的元素,提高处理效率。例如,计算满足条件的元素数量:
long count = list.parallelStream()
  .filter(s -> s.length() > 5)
  .count();

2. 短路操作

  。

  • anyMatch、allMatch、noneMatch:短路匹配:这些方法用于在流中进行短路匹配操作。
    • anyMatch:只要流中有一个元素满足条件就返回true。例如:
boolean anyStartsWithA = list.stream()
  .anyMatch(s -> s.startsWith("a"));
System.out.println(anyStartsWithA); // 输出: true
  • allMatch:只有流中所有元素都满足条件才返回 true。例如:
boolean allStartsWithA = list.stream()
  .allMatch(s -> s.startsWith("a"));
System.out.println(allStartsWithA); // 输出: false
  • noneMatch:如果流中没有元素满足条件则返回 true。例如:
boolean noneStartsWithZ = list.stream()
  .noneMatch(s -> s.startsWith("z"));
System.out.println(noneStartsWithZ); // 输出: true

3. 分组和分区

  。

  • Collectors.groupingBy:分组:使用 groupingBy 方法可以根据指定的分类函数将流中的元素分组到一个 Map 中。例如,根据字符串的首字母进行分组:
Map<Character, List<String>> groupedByFirstLetter = list.stream()
  .collect(Collectors.groupingBy(s -> s.charAt(0)));
System.out.println(groupedByFirstLetter); // {a=[apple], b=[banana], c=[cherry]}
  • Collectors.partitioningBy:分区partitioningBy 方法根据指定的布尔条件将流中的元素分区到一个 Map 中,键为 true 和 false。例如,根据字符串长度是否大于 5 进行分区:
Map<Boolean, List<String>> partitioned = list.stream()
  .collect(Collectors.partitioningBy(s -> s.length() > 5)); // {false=[apple], true=[banana, cherry]}
System.out.println(partitioned);

4. 收集到 Map

  。

  • Collectors.toMap:收集到 Map:使用 toMap 方法可以将流中的元素收集到一个 Map 中,需要指定键和值的映射函数。例如:
Map<String, Integer> map = list.stream()
  .collect(Collectors.toMap(Function.identity(), String::length));
System.out.println(map);

4、flatMap 用法

  。

flatMap 方法用于将流中的每个元素转换为另一个流,然后将这些流扁平化成一个单一的流。这在处理嵌套集合时非常有用。例如:
List<List<String>> listOfLists = Arrays.asList(
    Arrays.asList("apple", "banana"),
    Arrays.asList("cherry", "date"),
    Arrays.asList("fig", "grape")
);

// 使用 flatMap 将嵌套列表扁平化
List<String> flattenedList = listOfLists.stream()
  .flatMap(List::stream)
  .collect(Collectors.toList());

System.out.println(flattenedList); // 输出: [apple, banana, cherry, date, fig, grape]

5、peek 用法

  。

  • peek 方法主要用于调试,它允许你在流的每个元素上执行某个操作(例如打印),而不会改变流中的元素。peek 返回一个新的流,其中包含与原始流相同的元素。例如:
List<String> list = Arrays.asList("apple", "banana", "cherry");

List<String> result = list.stream()
  .peek(s -> System.out.println("Processing: " + s)) // 打印每个元素
  .map(String::toUpperCase)
  .collect(Collectors.toList());

System.out.println(result); // 输出: [APPLE, BANANA, CHERRY]

6、limit 用法

  。

  • limit 方法用于限制流中的元素数量。例如:
List<String> list = Arrays.asList("apple", "banana", "cherry", "date", "fig", "grape");

List<String> limitedList = list.stream()
  .limit(3)
  .collect(Collectors.toList());

System.out.println(limitedList); // 输出: [apple, banana, cherry]

7、skip 用法

  。

  • skip 方法用于跳过流中的前 n 个元素。例如:
List<String> list = Arrays.asList("apple", "banana", "cherry", "date", "fig", "grape");

List<String> skippedList = list.stream()
  .skip(3)
  .collect(Collectors.toList());

System.out.println(skippedList); // 输出: [date, fig, grape]

8、min 和 max

  。

  • min 和 max 方法用于查找流中的最小值和最大值。例如:
List<Integer> numbers = Arrays.asList(10, 20, 30, 40, 50);

// 查找最小值
Optional<Integer> min = numbers.stream()
  .min(Integer::compareTo);

System.out.println(min.get()); // 输出: 10

// 查找最大值
Optional<Integer> max = numbers.stream()
  .max(Integer::compareTo);

System.out.println(max.get()); // 输出: 50

9、findAny 和 findFirst

  。

  • findAny 和 findFirst 方法用于查找流中的任意元素和第一个元素。例如:
List<String> list = Arrays.asList("apple", "banana", "cherry");

// 查找任意一个元素
Optional<String> anyElement = list.stream().findAny();

System.out.println(anyElement.get()); // 输出: apple (或 banana 或 cherry)

// 查找第一个元素
Optional<String> firstElement = list.stream().findFirst();

System.out.println(firstElement.get()); // 输出: apple

通过以上对 Java 中 Stream 流的全面介绍,我们可以看到它在数据处理方面提供了强大而灵活的功能。合理运用 Stream 流可以使我们的代码更加简洁、高效,提高编程的效率和代码的可读性。在实际开发中,根据具体的需求选择合适的 Stream 流操作方法,可以更好地处理集合数据,实现复杂的数据处理逻辑.

  。

  。

  。

  。

  。

  。

  。

  。

  。

在 Java 编程中,Stream 流提供了一种高效、便捷的方式来处理集合数据。它可以让我们以声明式的方式对数据进行各种操作,如过滤、映射、排序、聚合等,大大简化了数据处理的代码编写。本文将详细介绍 Java 中 Stream 流的用法,包括基础用法、中级用法、高级用法以及一些特殊方法的使用。

1、基础用法

1. 创建 Stream


  • 从集合创建 Stream:通过调用集合的 stream() 方法可以创建一个顺序流。例如:

收起

java
 
List<String> list = Arrays.asList("apple", "banana", "cherry");
Stream<String> stream1 = list.stream();

  • 从数组创建 Stream:使用 Arrays.stream() 方法可以从数组创建流。例如:

收起

java
 
String[] array = {"apple", "banana", "cherry"};
Stream<String> stream2 = Arrays.stream(array);

2. 中间操作


  • filter:过滤元素:使用 filter 方法可以根据指定的条件过滤流中的元素。例如,以下代码过滤出以 "a" 开头的字符串:

收起

java
 
list.stream()
   .filter(s -> s.startsWith("a"))
   .forEach(System.out::println); // 输出: apple

  • map:转换元素map 方法可以将流中的每个元素按照指定的函数进行转换。例如,将字符串转换为大写:

收起

java
 
list.stream()
   .map(String::toUpperCase)
   .forEach(System.out::println); // 输出: APPLE BANANA CHERRY

3. 终止操作


  • forEach:遍历元素forEach 方法用于遍历流中的每个元素并执行指定的操作。例如:

收起

java
 
list.stream().forEach(System.out::println);

  • collect:收集结果到集合collect 方法可以将流中的元素收集到指定的集合中。例如,收集长度大于 5 的字符串到一个新的列表中:

收起

java
 
List<String> result1 = list.stream()
   .filter(s -> s.length() > 5)
   .collect(Collectors.toList());

// 或者使用 toList() 方法(Java 16 及以上版本)
List<String> result2 = list.stream()
   .filter(s -> s.length() > 5)
   .toList();

2、中级用法

1. 排序


  • sorted:自然排序或自定义排序sorted 方法可以对流中的元素进行排序。如果元素实现了 Comparable 接口,可以直接使用无参的 sorted 方法进行自然排序。例如:

收起

java
 
list.stream()
   .sorted()
   .forEach(System.out::println); // 输出: apple banana cherry

如果需要自定义排序规则,可以传入一个  Comparator 比较器。例如,按照字符串长度倒序排序:

收起

java
 
list.stream()
   .sorted(Comparator.reverseOrder())
   .forEach(System.out::println); // 输出: cherry banana apple

2. 去重


使用  distinct 方法可以去除流中的重复元素。例如:

收起

java
 
List<Integer> numbers = Arrays.asList(1, 2, 2, 3, 4, 4, 5);
List<Integer> distinctNumbers = numbers.stream()
   .distinct()
   .toList();

3. 聚合操作


  • reduce:归约操作reduce 方法可以对流中的元素进行归约操作,例如求和、求乘积等。例如,计算整数列表的总和:

收起

java
 
Optional<Integer> sum = numbers.stream()
   .reduce((a, b) -> a + b); // 可替换为.reduce(Integer::sum);
System.out.println(sum.get()); // 输出: 19

3、高级用法

1. 并行流


  • parallelStream:并行处理(提高效率):使用 parallelStream 方法可以创建一个并行流,它会在多个线程上并行处理流中的元素,提高处理效率。例如,计算满足条件的元素数量:

收起

java
 
long count = list.parallelStream()
   .filter(s -> s.length() > 5)
   .count();

2. 短路操作


  • anyMatch、allMatch、noneMatch:短路匹配:这些方法用于在流中进行短路匹配操作。
    • anyMatch:只要流中有一个元素满足条件就返回 true。例如:

收起

java
 
boolean anyStartsWithA = list.stream()
   .anyMatch(s -> s.startsWith("a"));
System.out.println(anyStartsWithA); // 输出: true

  • allMatch:只有流中所有元素都满足条件才返回 true。例如:

收起

java
 
boolean allStartsWithA = list.stream()
   .allMatch(s -> s.startsWith("a"));
System.out.println(allStartsWithA); // 输出: false

  • noneMatch:如果流中没有元素满足条件则返回 true。例如:

收起

java
 
boolean noneStartsWithZ = list.stream()
   .noneMatch(s -> s.startsWith("z"));
System.out.println(noneStartsWithZ); // 输出: true

3. 分组和分区


  • Collectors.groupingBy:分组:使用 groupingBy 方法可以根据指定的分类函数将流中的元素分组到一个 Map 中。例如,根据字符串的首字母进行分组:

收起

java
 
Map<Character, List<String>> groupedByFirstLetter = list.stream()
   .collect(Collectors.groupingBy(s -> s.charAt(0)));
System.out.println(groupedByFirstLetter); // {a=[apple], b=[banana], c=[cherry]}

  • Collectors.partitioningBy:分区partitioningBy 方法根据指定的布尔条件将流中的元素分区到一个 Map 中,键为 true 和 false。例如,根据字符串长度是否大于 5 进行分区:

收起

java
 
Map<Boolean, List<String>> partitioned = list.stream()
   .collect(Collectors.partitioningBy(s -> s.length() > 5)); // {false=[apple], true=[banana, cherry]}
System.out.println(partitioned);

4. 收集到 Map


  • Collectors.toMap:收集到 Map:使用 toMap 方法可以将流中的元素收集到一个 Map 中,需要指定键和值的映射函数。例如:

收起

java
 
Map<String, Integer> map = list.stream()
   .collect(Collectors.toMap(Function.identity(), String::length));
System.out.println(map);

4、flatMap 用法


flatMap 方法用于将流中的每个元素转换为另一个流,然后将这些流扁平化成一个单一的流。这在处理嵌套集合时非常有用。例如:

收起

java
 
List<List<String>> listOfLists = Arrays.asList(
    Arrays.asList("apple", "banana"),
    Arrays.asList("cherry", "date"),
    Arrays.asList("fig", "grape")
);

// 使用 flatMap 将嵌套列表扁平化
List<String> flattenedList = listOfLists.stream()
   .flatMap(List::stream)
   .collect(Collectors.toList());

System.out.println(flattenedList); // 输出: [apple, banana, cherry, date, fig, grape]

5、peek 用法


peek 方法主要用于调试,它允许你在流的每个元素上执行某个操作(例如打印),而不会改变流中的元素。 peek 返回一个新的流,其中包含与原始流相同的元素。例如:

收起

java
 
List<String> list = Arrays.asList("apple", "banana", "cherry");

List<String> result = list.stream()
   .peek(s -> System.out.println("Processing: " + s)) // 打印每个元素
   .map(String::toUpperCase)
   .collect(Collectors.toList());

System.out.println(result); // 输出: [APPLE, BANANA, CHERRY]

6、limit 用法


limit 方法用于限制流中的元素数量。例如:

收起

java
 
List<String> list = Arrays.asList("apple", "banana", "cherry", "date", "fig", "grape");

List<String> limitedList = list.stream()
   .limit(3)
   .collect(Collectors.toList());

System.out.println(limitedList); // 输出: [apple, banana, cherry]

7、skip 用法


skip 方法用于跳过流中的前  n 个元素。例如:

收起

java
 
List<String> list = Arrays.asList("apple", "banana", "cherry", "date", "fig", "grape");

List<String> skippedList = list.stream()
   .skip(3)
   .collect(Collectors.toList());

System.out.println(skippedList); // 输出: [date, fig, grape]

8、min 和 max


min 和  max 方法用于查找流中的最小值和最大值。例如:

收起

java
 
List<Integer> numbers = Arrays.asList(10, 20, 30, 40, 50);

// 查找最小值
Optional<Integer> min = numbers.stream()
   .min(Integer::compareTo);

System.out.println(min.get()); // 输出: 10

// 查找最大值
Optional<Integer> max = numbers.stream()
   .max(Integer::compareTo);

System.out.println(max.get()); // 输出: 50

9、findAny 和 findFirst


findAny 和  findFirst 方法用于查找流中的任意元素和第一个元素。例如:

收起

java
 
List<String> list = Arrays.asList("apple", "banana", "cherry");

// 查找任意一个元素
Optional<String> anyElement = list.stream().findAny();

System.out.println(anyElement.get()); // 输出: apple (或 banana 或 cherry)

// 查找第一个元素
Optional<String> firstElement = list.stream().findFirst();

System.out.println(firstElement.get()); // 输出: apple

通过以上对 Java 中 Stream 流的全面介绍,我们可以看到它在数据处理方面提供了强大而灵活的功能。合理运用 Stream 流可以使我们的代码更加简洁、高效,提高编程的效率和代码的可读性。在实际开发中,根据具体的需求选择合适的 Stream 流操作方法,可以更好地处理集合数据,实现复杂的数据处理逻辑。

最后此篇关于[Java]Stream流使用最多的方式的文章就讲到这里了,如果你想了解更多关于[Java]Stream流使用最多的方式的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

57 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com