一、什么是Stream流?
Stream流是Java 8引入的一种新特性,用于处理集合数据的一种高级抽象。它提供了一种简洁、优雅且高效的方式来对数据进行操作,使得我们可以以更直观、易读的方式表达数据操作逻辑。
Stream流将集合数据看作是一个序列或者流,通过一系列的操作方法来对数据进行处理。这些操作可以包括筛选(filter)、映射(map)、排序(sorted)、归约(reduce)等,以实现复杂的数据处理需求。
Stream流的设计目标是让我们专注于数据的处理逻辑,而不需要关心具体的遍历和操作细节。它隐藏了底层的实现细节,提供了链式操作的方式来组合多个操作,使得代码更加简洁、清晰。
与传统的迭代器或循环遍历方式相比,Stream流具有代码量少、可读性强、易于理解和维护等优势。它提供了丰富的操作方法,可以灵活地组合使用,从而实现各种复杂的数据处理任务。
三、创建Steam的方式?
下面详细介绍几种常用的创建方式,并提供相应的代码示例。请注意,示例代码均为Java 8及以上版本。
- 从集合(Collection)创建流:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
// 通过集合的stream()方法创建流
Stream<Integer> stream1 = numbers.stream();
// 通过集合的parallelStream()方法创建并行流
Stream<Integer> stream2 = numbers.parallelStream();
- 使用Stream.of()创建流:
Stream<String> stream = Stream.of("a", "b", "c");
- 使用数组创建流:
int[] array = {1, 2, 3, 4, 5};
// 通过Arrays.stream()创建流
IntStream stream1 = Arrays.stream(array);
// 通过Stream.of()和装箱操作创建流
Stream<Integer> stream2 = Stream.of(array).boxed();
- 使用Stream.iterate()创建无限流:
Stream<Integer> stream = Stream.iterate(0, n -> n + 2).limit(5);
stream.forEach(System.out::print);
// 02468
上述代码中,通过iterate方法生成一个从0开始的无限流,每个元素依次加2,为了方便演示,截取前五个数。
- 使用Stream.generate()创建无限流:
Stream<Double> stream = Stream.generate(Math::random);
stream.forEach(System.out::println);
// 0.617324218420578
// 0.932630935672188
// 0.7285489740415507
......
上述代码中,通过generate方法生成一个无限流,每个元素是一个随机生成的Double值。
二、Stream流具有哪些特性?
1.链式操作:Stream流支持链式操作,通过多个中间操作和一个终止操作组合在一起,形成一个操作流水线。常见的中间操作包括filter(筛选)、map(映射)、sorted(排序)、distinct(去重),常见例如:
int[] numbers = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
List<Integer> resultList = Arrays.stream(numbers)
.filter(x -> x > 5)
.map(x -> x * 2)
.sorted()
.distinct()
.boxed() // 将流中的元素包装为Integer类型
.collect(Collectors.toList());
System.out.println(resultList);
// [12, 14, 16, 18, 20]
2.懒加载:Stream流中的操作是延迟执行的,只有在终止操作调用时才会真正执行操作。这种机制可以提升性能,避免不必要的计算。
3.内部迭代:Stream流使用内部迭代来遍历和处理集合元素,相比于外部迭代(如for-each循环),内部迭代更加简洁方便,并且能够充分利用多核处理器的优势。
4.函数式编程:Stream流借鉴了函数式编程的思想,提供了丰富的操作方法来处理集合元素。常见的中间操作包括filter、map、sorted、distinct,常见的终止操作包括forEach(遍历处理)、collect(收集到集合)、reduce(归约)、count(计数),例如:
stream.forEach(System.out::println);
List<Integer> list = stream.collect(Collectors.toList());
Optional<Integer> result = stream.reduce((a, b) -> a + b);
long count = stream.count();
5.并行处理:Stream流可以进行并行处理,即在多个线程上同时执行操作,提高处理大量数据的效率。通过调用parallel方法,可以将Stream流切换为并行流。
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// 串行流处理
long startTime1 = System.currentTimeMillis();
int sum1 = numbers.stream()
.filter(n -> n % 2 == 0)
.mapToInt(Integer::intValue)
.sum();
long endTime1 = System.currentTimeMillis();
System.out.println("串行流处理结果:" + sum1 + ",耗时:" + (endTime1 - startTime1) + "ms");
// 串行流处理结果:30,耗时:34ms
// 并行流处理
long startTime2 = System.currentTimeMillis();
int sum2 = numbers.parallelStream()
.filter(n -> n % 2 == 0)
.mapToInt(Integer::intValue)
.sum();
long endTime2 = System.currentTimeMillis();
System.out.println("并行流处理结果:" + sum2 + ",耗时:" + (endTime2 - startTime2) + "ms");
// 并行流处理结果:30,耗时:2ms
总之,运用Stream流可以使我们的代码更加简洁、高效,提高开发效率,同时也提升了代码的可读性和可维护性,对于日常开发中处理集合数据具有重要的意义。