Java基础知识——流

一、流的概念

定义

📕流是用于操作数据源(如集合、数组等)生成的元素序列的抽象数据结构。流就像花洒一样,通过不同的过滤器和形状来改变数据流的形式和处理方式。

特性

惰性执行

🍇流的中间操作(如 filter, map 等)不会立即执行,而是在终端操作(如 forEach, collect 等)触发时才执行。这种特性允许流在进行多个中间操作时,只遍历一次数据源,从而提高效率。

不存储数据

🍬流本身不存储数据,它只是数据的视图或操作的管道。流操作分为中间操作和终端操作。

import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

public class LazyExecution {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("John", "Jane", "Jack", "Doe");

        // 创建流并进行一系列中间操作
        Stream<String> stream = names.stream()
            .filter(name -> {
                System.out.println("Filtering: " + name);
                return name.startsWith("J");
            })
            .map(name -> {
                System.out.println("Mapping: " + name);
                return name.toUpperCase();
            });

        System.out.println("Before terminal operation");

        // 终端操作开始时,中间操作才会执行
        stream.forEach(System.out::println);

        System.out.println("After terminal operation");
    }
}



二、流的创建

从集合创建

// 通过调用stream()函数进行流的创建
List<String> list = Arrays.asList("a", "b", "c");
Stream<String> streamFromList = list.stream();

从数组创建

// 通过调用Array中的stream()方法,将集合传进去进行流的创建
String[] array = ["a", "b", "c"];
Stream<String> streamFromArry = Arrays.stream(array);

使用 Stream.of() 方法

// 直接调用Stream.of()方法,传入若干字符串进行流的创建
Stream<String> streamOf = Stream.of("a", "b", "c");



三、流的操作

⌨流操作分为中间操作和终端操作。中间操作返回的是流本身,可以进行链式调用。终端操作返回的是结果(如 List、数组、计算值等)。

中间操作

filter:过滤流中的元素。

list.stream().filter(s -> s.startsWith("a")).forEach(System.out::println);

map:将元素映射到另一个形式。

list.stream().map(String::toUpperCase).forEach(System.out::println);

flatMap:将每个元素映射为流,然后将这些流合并为一个流。

List<List<String>> listOfLists = Arrays.asList(
    Arrays.asList("a", "b"),
    Arrays.asList("c", "d")
);
listOfLists.stream().flatMap(List::stream).forEach(System.out::println);

sorted:对流中的元素进行排序。

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

distinct:去除流中的重复元素。

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

limit:截取流中的前 n 个元素。

list.stream().limit(2).forEach(System.out::println);

skip:跳过流中的前 n 个元素。

list.stream().skip(2).forEach(System.out::println);

示例代码

import java.util.*;
import java.util.stream.*;

public class IntermediateOperations {
    public static void main(String[] args) {
        List<String> list = Arrays.asList("a", "b", "c", "a");

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

        // map
        list.stream()
            .map(String::toUpperCase)
            .forEach(System.out::println); // 输出: A, B, C, A

        // sorted
        list.stream()
            .sorted()
            .forEach(System.out::println); // 输出: a, a, b, c

        // distinct
        list.stream()
            .distinct()
            .forEach(System.out::println); // 输出: a, b, c
    }
}


终端操作

forEach:对流中的每个元素执行操作。

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

collect:将流中的元素收集到集合、列表或映射中。

List<String> filteredList = list.stream()
                                .filter(s -> s.startsWith("a"))
                                .collect(Collectors.toList());

toArray:将流中的元素转换为数组。

String[] array = list.stream().toArray(String[]::new);

reduce:对流中的元素进行合并操作。

Optional<String> reduced = list.stream().reduce((s1, s2) -> s1 + "#" + s2);

count:计算流中的元素数量。

long count = list.stream().count();

anyMatch, allMatch, noneMatch:匹配流中的元素。

boolean anyMatch = list.stream().anyMatch(s -> s.startsWith("a"));
boolean allMatch = list.stream().allMatch(s -> s.length() == 1);
boolean noneMatch = list.stream().noneMatch(s -> s.startsWith("z"));

findFirst,findAny:查找流中的元素。

Optional<String> first = list.stream().findFirst();
Optional<String> any = list.stream().findAny();

示例代码

import java.util.*;
import java.util.stream.*;

public class TerminalOperations {
    public static void main(String[] args) {
        List<String> list = Arrays.asList("a", "b", "c", "a");

        // forEach
        list.stream()
            .forEach(System.out::println); // 输出: a, b, c, a

        // collect
        List<String> filteredList = list.stream()
                                        .filter(s -> s.startsWith("a"))
                                        .collect(Collectors.toList());
        System.out.println(filteredList); // 输出: [a, a]

        // toArray
        String[] array = list.stream()
                             .toArray(String[]::new);
        System.out.println(Arrays.toString(array)); // 输出: [a, b, c, a]

        // reduce
        Optional<String> reduced = list.stream()
                                       .reduce((s1, s2) -> s1 + "#" + s2);
        reduced.ifPresent(System.out::println); // 输出: a#b#c#a

        // count
        long count = list.stream()
                         .count();
        System.out.println(count); // 输出: 4

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

        boolean allMatch = list.stream()
                               .allMatch(s -> s.length() == 1);
        System.out.println(allMatch); // 输出: true

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

        // findFirst, findAny
        Optional<String> first = list.stream()
                                     .findFirst();
        first.ifPresent(System.out::println); // 输出: a

        Optional<String> any = list.stream()
                                   .findAny();
        any.ifPresent(System.out::println); // 可能输出: a
    }
}



四、流的并行处理

✌ 通过调用 parallelStream() 方法,可以将流转换为并行流,以提高性能。并行流将数据分割成多个块,并在多个线程中进行处理,从而加速计算过程。

import java.util.*;
import java.util.stream.*;

public class ParallelStream {
    public static void main(String[] args) {
        List<String> list = Arrays.asList("a", "b", "c", "d");

        // 并行流
        list.parallelStream()
            .forEach(System.out::println); // 输出顺序不定
    }
}



五、总结

  • 流(Streams):提供了一种功能强大的数据处理方式,支持通过中间操作和终端操作对数据进行转换和处理。
  • 中间操作:如 filter, map, sorted 等,支持链式调用,惰性执行。
  • 终端操作:如 forEach, collect, reduce 等,触发流的处理并产生结果。
  • 并行流:通过 parallelStream() 提供并行处理能力,适用于需要大量计算的场景。

通过合理使用流,能够提高代码的可读性和性能。流的操作符及其特性是现代 Java 编程中非常重要的知识点。

  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值