Stream流中各阶段方法说明及组合示例

常用方法

Stream方法组合使用

第一种介绍字符串集合可进行的操作

import java.util.Arrays;
import java.util.List;

public class StreamExample {
    
    
    public static void main(String[] args) {
    
    
        List<String> list = Arrays.asList("apple", "banana", "cat", "dog", "egg");

        long count = list.stream()                  // 创建Stream
                        .filter(s -> s.length() == 3) // 过滤长度为3的元素
                        .map(String::toUpperCase)     // 转换为大写
                        .sorted()                     // 排序
                        .count();                     // 统计元素个数

        System.out.println(count); // 输出:3
    }
}

上述代码中,首先创建了一个包含5个字符串的List,然后通过stream()方法将其转换为一个Stream。接着对Stream进行操作,包括过滤、转换为大写、排序和统计元素个数。最后将统计结果打印出来。
具体步骤和注释如下:

  • list.stream(): 将List转换为一个Stream对象。
  • filter(s -> s.length() == 3): 对Stream中的元素进行过滤,只保留长度为3的元素。
  • map(String::toUpperCase): 将Stream中的元素转换为大写。
  • sorted(): 对Stream中的元素进行排序。
  • count(): 统计Stream中元素的个数。
  • System.out.println(count): 将统计结果打印出来。

第二种介绍int类型集合可进行的操作

下面的代码演示了如何使用Stream的方法组合来完成以下三个操作:

找出所有大于5的偶数,并将结果存储到一个列表中;
计算列表中所有元素的平方和;
找出列表中的最大值和最小值。

import java.util.Arrays;
import java.util.List;

public class StreamDemo {
    
    

    public static void main(String[] args) {
    
    
        // 创建一个包含整数的列表
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

        // 找出所有大于5的偶数,并将结果存储到一个列表中
        List<Integer> result = numbers.stream()
                .filter(n -> n > 5)          // 过滤出大于5的数
                .filter(n -> n % 2 == 0)    // 过滤出偶数
                .collect(Collectors.toList()); // 将结果存储到一个列表中

        System.out.println(result);

        // 计算列表中所有元素的平方和
        int sum = numbers.stream()
                .mapToInt(n -> n * n)        // 将元素映射为它的平方
                .sum();                     // 计算和

        System.out.println(sum);

        // 找出列表中的最大值和最小值
        IntSummaryStatistics stats = numbers.stream()
                .mapToInt((x) -> x)          // 将Stream<Integer>转换为IntStream
                .summaryStatistics();       // 计算统计信息

        System.out.println("最大值: " + stats.getMax());
        System.out.println("最小值: " + stats.getMin());
    }
}

下面分别对这三个操作进行详细的解释:

操作1:找出所有大于5的偶数,并将结果存储到一个列表中

首先,使用filter()方法过滤出大于5的数,然后使用另一个filter()方法过滤出偶数,最后使用collect()方法将结果存储到一个列表中。

操作2:计算列表中所有元素的平方和

首先,使用mapToInt()方法将每个元素映射为它的平方,然后使用sum()方法计算和。

操作3:找出列表中的最大值和最小值

首先,使用mapToInt()方法将Stream转换为IntStream,然后使用summaryStatistics()方法计算统计信息,包括最大值和最小值。

第三种介绍collect()和filter()组合的使用方式

在下面的代码中,首先创建了一个包含数字1到10的List。然后,调用stream()方法将List转换为一个Stream。接着,调用filter()方法对Stream中的元素进行过滤操作,只保留偶数元素。最后,调用collect()方法将结果收集到一个新的List中。

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

public class StreamDemo {
    
    
    public static void main(String[] args) {
    
    
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

        List<Integer> result = numbers.stream()
                .filter(number -> number % 2 == 0)
                .collect(Collectors.toList());

        System.out.println(result);
    }
}

将一个包含学生信息的List转换为一个以学生名字为键,学生对象为值的Map。
在下面的代码中,首先创建了一个包含三个学生信息的List。然后,调用stream()方法将List转换为一个Stream。接着,调用collect()方法,并传递一个Collectors.toMap()方法作为参数。在toMap()方法中,使用Student::getName将学生名字作为Map的键,使用student -> student将学生对象作为Map的值。最终,将结果存储到一个Map对象中。

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class StreamDemo {
    
    

    public static void main(String[] args) {
    
    
        List<Student> students = Arrays.asList(
                new Student("Tom", 18),
                new Student("Jack", 20),
                new Student("Lucy", 19)
        );

        Map<String, Student> result = students.stream()
                .collect(Collectors.toMap(Student::getName, student -> student));

        System.out.println(result);
    }
}

class Student {
    
    
    private String name;
    private int age;

    public Student(String name, int age) {
    
    
        this.name = name;
        this.age = age;
    }

    public String getName() {
    
    
        return name;
    }

    public int getAge() {
    
    
        return age;
    }

    @Override
    public String toString() {
    
    
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

方法对比flatMap()和filter()

这两个方法都可以用来筛选流中的数据,但它们的实现方式和作用是不同的。
flatMap()方法的作用是将一个Stream中的每个元素都转换为一个新的流,然后将这些流合并成一个新的流。换句话说,flatMap()方法用来处理嵌套的流结构,并将它们扁平化为一个单一的流。因此,flatMap()方法常用于将嵌套的集合或数组展开为一个单独的流,以方便进一步的处理。
下面是一个使用flatMap()方法的示例代码:

List<List<Integer>> numbers = Arrays.asList(Arrays.asList(1, 2), Arrays.asList(3, 4), Arrays.asList(5, 6));
List<Integer> flattenedNumbers = numbers.stream()
        .flatMap(Collection::stream)
        .collect(Collectors.toList());
System.out.println(flattenedNumbers);
// Output: [1, 2, 3, 4, 5, 6]

在上面的代码中,首先创建了一个包含多个集合的列表numbers。然后,调用stream()方法将这个列表转换为一个Stream。接着,使用flatMap()方法将每个集合都转换为一个新的流,并将这些流合并为一个新的流。最后,使用collect()方法将所有的元素收集到一个新的List中。
filter()方法的作用是根据指定的条件筛选出符合条件的元素,并将它们收集到一个新的Stream中。换句话说,filter()方法用于对Stream中的元素进行条件过滤。因此,filter()方法常用于从一个大的数据集合中,选择符合条件的元素,以用于进一步的处理。
下面是一个使用filter()方法的示例代码:

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

在上面的代码中,首先创建了一个包含多个整数的列表numbers。然后,调用stream()方法将这个列表转换为一个Stream。接着,使用filter()方法过滤出所有偶数,并将它们收集到一个新的Stream中。最后,使用collect()方法将所有偶数收集到一个新的List中。
需要注意的是,flatMap()和filter()方法都是用于处理Stream中的数据,并返回一个新的Stream,它们常常被用于组合使用,以达到对数据进行更复杂处理的目的。

Stream的创建

可以通过以下方式创建Stream:

1. 从集合或数组创建

可以通过Collection.stream()或Arrays.stream()方法来创建Stream。

List<String> list = Arrays.asList("a", "b", "c"); 
Stream<String> stream = list.stream();

2. 使用Stream.of()创建

使用Stream.of()方法创建一个Stream。

Stream<String> stream = Stream.of("a", "b", "c");

3. 使用Stream.iterate()创建

使用Stream.iterate()方法创建一个无限流。

Stream<Integer> stream = Stream.iterate(0, n -> n + 2);

4. 使用Stream.generate()创建

使用Stream.generate()方法创建一个无限流。

Stream<Double> stream = Stream.generate(Math::random);

Stream的中间操作

中间操作是指对数据源进行处理并返回一个Stream对象的操作,可以对数据源进行筛选、映射、去重、排序等操作。

以下是常用的Stream中间操作:

1. filter

该方法用于通过设置的条件过滤出元素,返回一个新的Stream对象。

Stream<String> stream = Stream.of("apple", "banana", "orange", "pear"); 
stream.filter(s -> s.length() > 5).forEach(System.out::println);

2. map

该方法用于将元素按照某种规则进行转换,返回一个新的Stream对象。

Stream<String> stream = Stream.of("apple", "banana", "orange", "pear"); 
stream.map(String::toUpperCase).forEach(System.out::println);

3. flatMap

该方法用于将一个Stream中的每个元素转换为另一个Stream,然后将所有Stream中的元素合并成一个Stream,返回一个新的Stream对象。
具体来说,flatMap()方法接收一个函数作为参数,这个函数将一个元素转换为一个新的流。然后,flatMap()方法将所有这些新的流合并成一个新的流,最后返回这个新的流。如果这个函数返回的是一个空的流,那么这个流中就不会包含任何元素。

Stream<List<Integer>> stream = Stream.of(Arrays.asList(1, 2), Arrays.asList(3, 4)); 
stream.flatMap(Collection::stream).forEach(System.out::println);

4. distinct

该方法用于对Stream中的元素进行去重,返回一个新的Stream对象。

Stream<String> stream = Stream.of("apple", "banana", "orange", "apple"); 
stream.distinct().forEach(System.out::println);

5. sorted

该方法用于对Stream中的元素进行排序,返回一个新的Stream对象。

Stream<String> stream = Stream.of("apple", "banana", "orange", "pear"); 
stream.sorted().forEach(System.out::println);

6. peek

该方法用于在执行Stream中的下一个操作时对元素进行操作,返回一个新的Stream对象。

Stream<String> stream = Stream.of("apple", "banana", "orange", "pear"); 
stream.peek(s -> System.out.println("before filter: " + s)).filter(s -> s.length() > 5) .peek(s -> System.out.println("after filter: " + s)).forEach(System.out::println);

7. limit

该方法用于截取Stream中前n个元素,返回一个新的Stream对象。

Stream<String> stream = Stream.of("apple", "banana", "orange", "pear"); 
stream.limit(2).forEach(System.out::println);

8. skip

该方法用于跳过Stream中前n个元素,返回一个新的Stream对象。

Stream<String> stream = Stream.of("apple", "banana", "orange", "pear"); 
stream.skip(2).forEach(System.out::println);

9. parallel

该方法用于将Stream转换为并行流,返回一个新的Stream对象。

Stream<String> stream = Stream.of("apple", "banana", "orange", "pear"); 
stream.parallel().forEach(System.out::println);

10. sequential

该方法用于将Stream转换为串行流,返回一个新的Stream对象。

Stream<String> stream = Stream.of("apple", "banana", "orange", "pear"); 
stream.parallel().sequential().forEach(System.out::println);

Stream的终止操作

终止操作是指对Stream进行最终操作,产生一个结果或副作用,但不再返回Stream对象。

以下是常用的Stream终止操作:

1. forEach

该方法用于对Stream中的元素进行遍历操作。

Stream<String> stream = Stream.of("apple", "banana", "orange", "pear"); 
stream.forEach(System.out::println);

2. toArray

该方法用于将Stream中的元素转换为数组。

Stream<String> stream = Stream.of("apple", "banana", "orange", "pear");
 String[] strArr = stream.toArray(String[]::new);

3. reduce

该方法用于将Stream中的所有元素按照指定的规则进行归约操作,返回一个Optional对象。

Stream<Integer> stream = Stream.of(1, 2, 3, 4); Optional<Integer> result = stream.reduce((x, y) -> x + y); 
result.ifPresent(System.out::println);

4. collect

该方法用于将Stream中的元素收集到一个集合中,返回一个新的集合对象。

Stream<String> stream = Stream.of("apple", "banana", "orange", "pear"); List<String> list = stream.collect(Collectors.toList());

5. count

该方法用于计算Stream中的元素个数,返回一个long类型的值。

Stream<String> stream = Stream.of("apple", "banana", "orange", "pear");
long count = stream.count();
System.out.println(count);

6. anyMatch

该方法用于判断Stream中是否存在满足指定条件的元素,返回一个boolean类型的值。

Stream<Integer> stream = Stream.of(1, 2, 3, 4); boolean result = stream.anyMatch(x -> x > 2); 
System.out.println(result);

7. allMatch

该方法用于判断Stream中的所有元素是否都满足指定条件,返回一个boolean类型的值。

Stream<Integer> stream = Stream.of(1, 2, 3, 4); boolean result = stream.allMatch(x -> x > 0); 
System.out.println(result);

8. noneMatch

该方法用于判断Stream中的所有元素是否都不满足指定条件,返回一个boolean类型的值。

Stream<Integer> stream = Stream.of(1, 2, 3, 4); boolean result = stream.noneMatch(x -> x > 5); 
System.out.println(result);

9. findAny

该方法用于获取Stream中的任意一个元素,返回一个Optional对象。

Stream<Integer> stream = Stream.of(1, 2, 3, 4); Optional<Integer> result = stream.findAny(); 
result.ifPresent(System.out::println);

10. findFirst

该方法用于获取Stream中的第一个元素,返回一个Optional对象。

​​

Stream<Integer> stream = Stream.of(1, 2, 3, 4); Optional<Integer> result = stream.findFirst(); 
result.ifPresent(System.out::println);

猜你喜欢

转载自blog.csdn.net/pengjun_ge/article/details/130406016