Stream流是Java 8引入的一种新的数据处理方式,它提供了一种更简洁、更灵活的方式来处理集合数据。通过使用Stream流,可以以声明式的方式对数据进行过滤、映射、排序、分组等操作,同时还能利用多核架构进行并行处理,提高代码的可读性和性能。
下面是一些常见的Stream流的使用示例:
- 创建Stream流:
可以通过集合、数组或者直接调用Stream类的静态方法来创建Stream流。
List<String> list = Arrays.asList("apple", "banana", "orange");
Stream<String> stream1 = list.stream();
String[] array = {"cat", "dog", "elephant"};
Stream<String> stream2 = Arrays.stream(array);
Stream<String> stream3 = Stream.of("red", "green", "blue");
- 转换操作:
Stream流提供了一系列的转换操作,如map、filter、sorted等,用于对流中的元素进行映射、过滤和排序等操作。
List<String> list = Arrays.asList("apple", "banana", "orange");
Stream<String> stream = list.stream();
// 使用map进行映射操作
Stream<Integer> lengthStream = stream.map(String::length);
// 使用filter进行过滤操作
Stream<Integer> filteredStream = lengthStream.filter(len -> len > 5);
// 使用sorted进行排序操作
Stream<Integer> sortedStream = filteredStream.sorted();
- 终端操作:
Stream流的终端操作会触发流的处理并产生最终的结果,例如forEach、collect、reduce等。
List<String> list = Arrays.asList("apple", "banana", "orange");
Stream<String> stream = list.stream();
// 使用forEach进行元素遍历
stream.forEach(System.out::println);
// 使用collect进行集合收集
List<String> collectedList = stream.collect(Collectors.toList());
// 使用reduce进行元素聚合
Optional<String> reducedString = stream.reduce((s1, s2) -> s1 + ", " + s2);
- 并行流处理:
Stream流支持并行处理,可以通过调用parallel方法将其转换为并行流,充分利用多核处理器来提高处理速度。
List<String> list = Arrays.asList("apple", "banana", "orange");
Stream<String> parallelStream = list.parallelStream();
parallelStream.forEach(System.out::println);
这些示例演示了Stream流的基本使用方法,你可以根据具体的需求使用Stream流进行数据处理,它提供了丰富的操作方法来简化代码并提高效率。
Stream流支持许多常见的操作,可以按需进行数据处理和转换。以下是一些常见的Stream流操作:
-
转换操作:
- map:对流中的每个元素进行映射操作,生成一个新的流。
- filter:根据给定的条件对流中的元素进行过滤,只保留满足条件的元素。
- flatMap:对流中的每个元素进行映射操作,然后将映射结果连接成一个新的流。
- distinct:去除流中重复的元素,保留唯一的元素。
- sorted:对流中的元素进行排序。
- limit:限制流中元素的数量。
- skip:跳过流中的前n个元素。
- peek:对流中的每个元素进行处理,返回一个包含原始元素的新流。
-
聚合操作:
- forEach:对流中的每个元素执行指定的操作。
- collect:将流中的元素收集到一个集合或者其他数据结构中。
- reduce:根据给定的操作对流中的元素进行聚合操作,返回一个聚合结果。
- min:找到流中的最小元素。
- max:找到流中的最大元素。
- count:统计流中的元素数量。
- anyMatch:检查流中是否存在满足给定条件的元素。
- allMatch:检查流中的所有元素是否都满足给定条件。
- noneMatch:检查流中是否没有元素满足给定条件。
- findFirst:找到流中的第一个元素。
-
收集操作:
- toList:将流中的元素收集到一个List集合中。
- toSet:将流中的元素收集到一个Set集合中。
- toMap:将流中的元素按照指定的键值映射规则收集到一个Map中。
- joining:将流中的元素连接成一个字符串。
- summarizingInt/summarizingLong/summarizingDouble:对流中的元素进行统计,如计算元素的总数、最小值、最大值、平均值等。
-
并行流操作:
- parallel:将流转换为并行流,以便在多个线程上并行处理。
- sequential:将并行流转换为顺序流。
这些只是Stream流操作的一部分,Stream还提供了其他更高级的操作,如分组、分区、匹配、映射等。你可以根据具体的需求选择适合的操作来处理数据。
除了之前提到的常见操作,Stream流还支持一些其他高级操作,帮助进行更复杂的数据处理。以下是一些常见的高级操作:
-
分组(Grouping):
- groupingBy:根据指定的分类函数将流中的元素分组到一个Map中,键为分类结果,值为对应的元素列表。
- groupingByConcurrent:与groupingBy类似,但保证并发安全,适用于并行流。
- groupingByConcurrent与groupingBy的使用方式相同,只是在处理并行流时更高效。
-
分区(Partitioning):
- partitioningBy:根据指定的条件将流中的元素分成两个部分,满足条件的为一部分,不满足条件的为另一部分。返回一个Map,键为true和false,值为对应的元素列表。
-
聚合(Aggregating):
- averagingInt/averagingLong/averagingDouble:计算流中元素的平均值。
- summingInt/summingLong/summingDouble:计算流中元素的总和。
- summarizingInt/summarizingLong/summarizingDouble:计算流中元素的统计信息,如总数、最小值、最大值、平均值等。
- reducing:根据给定的二元操作对流中的元素进行归约操作。
-
匹配(Matching):
- anyMatch:检查流中是否存在满足给定条件的元素。
- allMatch:检查流中的所有元素是否都满足给定条件。
- noneMatch:检查流中是否没有元素满足给定条件。
- findFirst:找到流中的第一个元素。
-
映射(Mapping):
- mapToInt/mapToLong/mapToDouble:将流中的元素映射为int、long或double类型的流。
- flatMap:对流中的每个元素进行映射操作,然后将映射结果连接成一个新的流。
这些高级操作可以帮助你在处理数据时更灵活地进行操作,并根据具体的需求进行分组、聚合、分区和匹配等操作。Stream流提供了丰富的功能和方法,可以根据不同的场景选择合适的操作来处理数据。
除了之前提到的高级操作,Stream流还支持其他一些有用的操作,使得数据处理更加灵活和高效。以下是一些其他的高级操作:
-
排序(Sorting):
- sorted:对流中的元素进行排序,默认按自然顺序排序。
- sorted(Comparator):根据指定的Comparator对流中的元素进行排序。
-
迭代(Iteration):
- iterate:生成一个无限流,使用指定的种子值和迭代函数产生新的元素。
- generate:生成一个无限流,使用指定的Supplier函数产生新的元素。
-
并行流操作(Parallel Stream Operations):
- parallel:将流转换为并行流,以便在多个线程上并行处理。
- sequential:将并行流转换为顺序流。
-
窄化操作(Narrowing Operations):
- mapToXxx:将流中的元素映射为特定的基本类型,如mapToInt、mapToLong、mapToDouble。
- boxed:将基本类型的流转换为对应的包装类型的流。
-
及早求值操作(Eager Evaluation Operations):
- toArray:将流中的元素转换为数组。
- forEachOrdered:按照流的遍历顺序依次对每个元素执行操作。
- toArray/collect/summarizingXxx/…:触发流的处理并返回最终结果。
-
自定义操作(Custom Operations):
- 自定义中间操作:可以使用Stream的自定义操作,通过实现Stream接口中的抽象方法来定义自己的中间操作。
- 自定义终端操作:可以使用Stream的自定义操作,通过实现Stream接口中的抽象方法来定义自己的终端操作。
这些操作扩展了Stream流的功能和灵活性,使得数据处理更加方便和高效。你可以根据具体的需求选择适合的操作来处理数据,并结合多个操作构建复杂的数据处理流水线。