万字详解Stream流以及Lambda(看这一篇就够用)

什么是Stream流?

Stream流是Java 8中新增的一种处理集合数据的方式,它提供了一种类似于数据库操作的流式处理方式,可以对集合进行过滤、映射、排序、聚合等操作,使得集合操作更加简洁、高效。

Stream流主要有以下几个特点:

  • Stream流不是数据结构,不会改变源数据,而是通过对源数据的操作来产生新的数据流。
  • Stream流支持链式操作,可以进行多个操作的组合,使得代码更加简洁。
  • Stream流支持延迟操作,只有在终止操作时才会进行计算,可以提高程序的性能。
  • Stream流可以进行并行操作,利用多核处理器的性能优势,提高程序的计算速度。

如何使用Stream流?

使用Stream流可以分为以下几个步骤:

  1. 获取数据源:可以通过集合、数组、IO流等方式获取数据源。
  2. 转换为流:通过stream()、parallelStream()等方法将数据源转换为流。
  3. 中间操作:对流进行中间操作,如过滤、映射、排序、去重等操作,这些操作会返回一个新的流。
  4. 终止操作:对流进行终止操作,如收集、计数、查找、匹配等操作,这些操作会返回一个结果。

下面将分别介绍各个操作的方法和使用示例。

1.获取数据源

可以通过集合、数组、IO流等方式获取数据源。

使用集合获取数据源

List<String> list = Arrays.asList("apple", "banana", "orange", "grape", "watermelon");

使用数组获取数据源

String[] array = {
    
    "apple", "banana", "orange", "grape", "watermelon"};

2.转换为流

通过stream()、parallelStream()等方法将数据源转换为流。

将集合转换为流

List<String> list = Arrays.asList("apple", "banana", "orange", "grape", "watermelon");
Stream<String> stream = list.stream();

将数组转换为流

String[] array = {
    
    "apple", "banana", "orange", "grape", "watermelon"};
Stream<String> stream = Arrays.stream(array);

3.中间操作

对流进行中间操作,如过滤、映射、排序、去重等操作,这些操作会返回一个新的流。

过滤数据

过滤掉长度小于等于5的字符串:

List<String> list = Arrays.asList("apple", "banana", "orange", "grape", "watermelon");
Stream<String> stream = list.stream().filter(str -> str.length() > 5);

映射数据

提取出所有水果的名称:

List<Fruit> fruits = Arrays.asList(
    new Fruit("apple", "red"),
    new Fruit("banana", "yellow"),
    new Fruit("orange", "orange"),
    new Fruit("grape", "purple"),
    new Fruit("watermelon", "green")
);
Stream<String> stream = fruits.stream().map(Fruit::getName);

排序数据

按照水果名称进行排序:

List<String> list = Arrays.asList("apple", "banana", "orange", "grape", "watermelon");
Stream<String> stream = list.stream().sorted();

去重数据

去掉重复的水果名称:

List<String> list = Arrays.asList("apple", "banana", "orange", "grape", "watermelon", "apple", "banana");
Stream<String> stream = list.stream().distinct();

4.终止操作

对流进行终止操作,如收集、计数、查找、匹配等操作,这些操作会返回一个结果。

收集数据

将水果名称收集到一个列表中:

List<Fruit> fruits = Arrays.asList(
    new Fruit("apple", "red"),
    new Fruit("banana", "yellow"),
    new Fruit("orange", "orange"),
    new Fruit("grape", "purple"),
    new Fruit("watermelon", "green")
);
List<String> names = fruits.stream().map(Fruit::getName).collect(Collectors.toList());

计数数据

统计水果名称的数量:

List<String> list = Arrays.asList("apple", "banana", "orange", "grape", "watermelon", "apple", "banana");
long count = list.stream().count();

查找数据

查找第一个水果名称:

List<String> list = Arrays.asList("apple", "banana", "orange", "grape", "watermelon");
Optional<String> first = list.stream().findFirst();

匹配数据

判断是否包含某个水果名称:

List<String> list = Arrays.asList("apple", "banana", "orange", "grape", "watermelon");
boolean contains = list.stream().anyMatch(str -> str.equals("banana"));

如何使用Lambda表达式?

Lambda表达式可以在函数接口中使用,函数接口是指只包含一个抽象方法的接口。

Lambda表达式的基本语法:

(parameters) -> expression

其中,parameters为方法的参数列表,expression为方法体。

下面将分别介绍Lambda表达式的使用示例。

1.使用Lambda表达式作为参数

将Lambda表达式作为参数传递给另一个方法:

public void process(int num, IntConsumer consumer) {
    
    
    consumer.accept(num);
}

public static void main(String[] args) {
    
    
    LambdaExample example = new LambdaExample();

    // 使用Lambda表达式作为参数
    example.process(10, (num) -> System.out.println(num));

    // 使用Lambda表达式实现函数接口
    Function<Integer, Integer> square = (num) -> num * num;
    int result = square.apply(5);
    System.out.println(result);

    // 使用Lambda表达式简化集合操作
    List<String> list = Arrays.asList("apple", "banana", "orange", "grape", "watermelon");

    // 使用Lambda表达式实现筛选
    List<String> filteredList = list.stream().filter(str -> str.length() > 5).collect(Collectors.toList());

    // 使用Lambda表达式实现映射
    List<String> mappedList = list.stream().map(str -> str.toUpperCase()).collect(Collectors.toList());

    // 使用Lambda表达式实现排序
    List<String> sortedList = list.stream().sorted().collect(Collectors.toList());

    // 使用Lambda表达式实现去重
    List<String> distinctList = list.stream().distinct().collect(Collectors.toList());
}

2.使用Lambda表达式实现函数接口

使用Lambda表达式实现一个函数接口:

Function<Integer, Integer> square = (num) -> num * num;

3.使用Lambda表达式简化集合操作

Lambda表达式可以简化集合操作,如筛选、映射、排序、去重等操作。下面是一些常见的集合操作示例:

3.1 筛选操作

筛选操作可以通过filter方法实现,它可以根据条件筛选集合中的元素,并返回一个新的Stream流。例如,下面是一个筛选操作的示例:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
List<Integer> evenNumbers = numbers.stream()
                                    .filter(n -> n % 2 == 0)
                                    .collect(Collectors.toList());
System.out.println(evenNumbers); // [2, 4, 6, 8, 10]

该示例中,首先创建一个包含整数1到10的List集合,然后使用Stream流的filter方法筛选出其中的偶数,并将结果保存到一个新的List集合中。

3.2 映射操作

映射操作可以通过map方法实现,它可以将集合中的元素映射为另一个元素,并返回一个新的Stream流。例如,下面是一个映射操作的示例:

List<String> words = Arrays.asList("hello", "world", "java", "stream", "lambda");
List<Integer> lengths = words.stream()
                                .map(String::length)
                                .collect(Collectors.toList());
System.out.println(lengths); // [5, 5, 4, 6, 6]

该示例中,首先创建一个包含字符串的List集合,然后使用Stream流的map方法将每个字符串映射为它的长度,并将结果保存到一个新的List集合中。

3.3 排序操作

排序操作可以通过sorted方法实现,它可以对集合中的元素进行排序,并返回一个新的Stream流。例如,下面是一个排序操作的示例:

List<String> words = Arrays.asList("hello", "world", "java", "stream", "lambda");
List<String> sortedWords = words.stream()
                                    .sorted()
                                    .collect(Collectors.toList());
System.out.println(sortedWords); // [hello, java, lambda, stream, world]

该示例中,首先创建一个包含字符串的List集合,然后使用Stream流的sorted方法对字符串进行排序,并将结果保存到一个新的List集合中。

3.4 去重操作

去重操作可以通过distinct方法实现,它可以将集合中重复的元素去除,并返回一个新的Stream流。例如,下面是一个去重操作的示例:

List<Integer> numbers = Arrays.asList(1, 2, 3, 2, 4, 5, 4, 6, 7, 5);
List<Integer> distinctNumbers = numbers.stream()
                                            .distinct()
                                            .collect(Collectors.toList());
System.out.println(distinctNumbers); // [1, 2, 3, 4

Lambda表达式的使用场景
Lambda表达式适合处理以下场景:

  • 函数式接口:Lambda表达式可以作为函数式接口的实现。函数式接口只包含一个抽象方法的接口,可以使用Lambda表达式来实现该方法。
  • 集合操作:Stream流可以用于处理集合中的元素,如筛选、映射、排序、去重等操作,可以使用Lambda表达式来简化代码。
  • 多线程编程:Lambda表达式可以作为Runnable和Callable接口的实现,可以更方便地实现多线程编程。
  • GUI事件监听器:Lambda表达式可以用于处理GUI事件监听器中的事件处理方法,可以使得代码更加简洁。

Stream流和Lambda表达式的优点

使用Stream流和Lambda表达式有以下优点:

  1. 简洁:使用Stream流和Lambda表达式可以使代码更加简洁、可读,降低代码的复杂度。
  2. 易于维护:使用Stream流和Lambda表达式可以使代码更加易于维护,减少代码的重复性。
  3. 并发执行:Stream流可以支持并发执行,提高程序的执行效率。
  4. 高效:使用Stream流和Lambda表达式可以使代码更加高效,减少内存和CPU的开销。

结论

Stream流和Lambda表达式是Java 8中的两个重要特性,它们可以使得代码更加简洁、可读、灵活,同时可以提高代码的效率和可维护性。如果您还没有使用过Stream流和Lambda表达式,那么希望这篇教程能够帮助您入门。

猜你喜欢

转载自blog.csdn.net/xiangyuWA/article/details/129632852