📜  Java 8-流(1)

📅  最后修改于: 2023-12-03 14:42:12.687000             🧑  作者: Mango

Java 8-流

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);
操作流

流有两种操作:中间操作和终端操作。中间操作不会产生结果,而是返回一个新的流,可以有多个中间操作,从而组成多个操作链,最后由一个终端操作产生一个结果。

中间操作可以是过滤、变换、排序、去重等等,终端操作可以是计数、查找、匹配、聚合等等。

中间操作

以下是一些常用的中间操作。

map

对流中的每个元素应用一个函数,并将结果放入一个新的流中。

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]

filter

从流中过滤出符合条件的元素,并将结果放入一个新的流中。

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"]

distinct

去掉流中重复的元素。

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]

sorted

对流中元素进行排序。

List<String> strings = Arrays.asList("foo", "bar", "baz", "foobar");
List<String> sortedStrings = strings.stream().sorted().collect(Collectors.toList());
// sortedStrings: ["bar", "baz", "foo", "foobar"]
终端操作

以下是一些常用的终端操作。

forEach

对每个元素执行指定的操作。

List<Integer> nums = Arrays.asList(1, 2, 3, 4, 5);
nums.stream().forEach(System.out::println);

count

返回流中元素的总数。

List<Integer> nums = Arrays.asList(1, 2, 3, 4, 5);
long count = nums.stream().count();
// count: 5

reduce

将流中的元素进行归约操作,返回一个最终结果。

List<Integer> nums = Arrays.asList(1, 2, 3, 4, 5);
Optional<Integer> sum = nums.stream().reduce((x, y) -> x + y);
// sum: 15

collect

将流中的元素收集到一个容器中。

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();
总结

流提供了一种更加简洁、高效的处理数据集合的方式,它的中间操作和终端操作的灵活组合可以实现各种复杂的操作。并行流可以进一步提高处理速度。