📅  最后修改于: 2023-12-03 14:42:12.687000             🧑  作者: Mango
Java 8引入了一种新的类似于集合的概念,叫做流(Stream)。它是一种用便捷、清晰的方式处理数据集合的方法。与集合不同的是,流的数据是在需要时才计算的,也就是说,只有按需计算,没有缓存。这样在处理大数据集合时,它比集合更加高效。
创建流可以有多种方式,包括创建空流、通过集合或数组创建流等。
用stream()
或parallelStream()
方法从集合创建一个流。
List<String> list = Arrays.asList("a", "b", "c");
Stream<String> stream = list.stream(); // 串行流
Stream<String> parallelStream = list.parallelStream(); // 并行流
用Arrays.stream()
方法从数组创建一个流。
int[] array = {1, 2, 3};
IntStream stream = Arrays.stream(array);
还有一些其他方式可以创建流,如从文件、从生成器、从无限序列等。
Stream<String> streamOfArray = Stream.of("a", "b", "c");
Stream<String> streamBuilder = Stream.<String>builder().add("a").add("b").add("c").build();
Stream<String> streamGenerated = Stream.generate(() -> "element").limit(10);
Stream<Integer> streamIterated = Stream.iterate(40, n -> n + 2).limit(20);
流有两种操作:中间操作和终端操作。中间操作不会产生结果,而是返回一个新的流,可以有多个中间操作,从而组成多个操作链,最后由一个终端操作产生一个结果。
中间操作可以是过滤、变换、排序、去重等等,终端操作可以是计数、查找、匹配、聚合等等。
以下是一些常用的中间操作。
对流中的每个元素应用一个函数,并将结果放入一个新的流中。
List<Integer> nums = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> squares = nums.stream().map(n -> n * n).collect(Collectors.toList());
// squares: [1, 4, 9, 16, 25]
从流中过滤出符合条件的元素,并将结果放入一个新的流中。
List<String> strings = Arrays.asList("foo", "bar", "baz", "foobar");
List<String> foos = strings.stream().filter(s -> s.contains("foo")).collect(Collectors.toList());
// foos: ["foo", "foobar"]
去掉流中重复的元素。
List<Integer> nums = Arrays.asList(1, 2, 2, 3, 3, 3, 4, 4, 4, 4);
List<Integer> uniqueNums = nums.stream().distinct().collect(Collectors.toList());
// uniqueNums: [1, 2, 3, 4]
对流中元素进行排序。
List<String> strings = Arrays.asList("foo", "bar", "baz", "foobar");
List<String> sortedStrings = strings.stream().sorted().collect(Collectors.toList());
// sortedStrings: ["bar", "baz", "foo", "foobar"]
以下是一些常用的终端操作。
对每个元素执行指定的操作。
List<Integer> nums = Arrays.asList(1, 2, 3, 4, 5);
nums.stream().forEach(System.out::println);
返回流中元素的总数。
List<Integer> nums = Arrays.asList(1, 2, 3, 4, 5);
long count = nums.stream().count();
// count: 5
将流中的元素进行归约操作,返回一个最终结果。
List<Integer> nums = Arrays.asList(1, 2, 3, 4, 5);
Optional<Integer> sum = nums.stream().reduce((x, y) -> x + y);
// sum: 15
将流中的元素收集到一个容器中。
List<Integer> nums = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> evenNums = nums.stream().filter(n -> n % 2 == 0).collect(Collectors.toList());
// evenNums: [2, 4]
在处理一些庞大的数据集合时,流的并行流可以带来很大的性能提升。并行流是将流中的元素分成多个部分并行处理的,提高了处理的速度。
List<Integer> nums = IntStream.range(1, 1_000_000).boxed().collect(Collectors.toList());
long start = System.currentTimeMillis();
long count1 = nums.stream().filter(n -> n % 2 == 0).count();
long end1 = System.currentTimeMillis();
long count2 = nums.parallelStream().filter(n -> n % 2 == 0).count();
long end2 = System.currentTimeMillis();
流提供了一种更加简洁、高效的处理数据集合的方式,它的中间操作和终端操作的灵活组合可以实现各种复杂的操作。并行流可以进一步提高处理速度。