java Stream API的使用

Java Stream API 是 Java 8 引入的一个重要特性,它提供了一种高效且易于使用的处理集合的方式。Stream API 支持函数式编程风格,可以对集合进行复杂的转换和操作,如过滤、映射、排序、聚合等。

Stream API 的基本概念

Stream API 主要有三个核心组件:

  1. 源(Source):数据流的来源,通常是集合(如 ListSet 等)或其他数据结构。
  2. 中间操作(Intermediate Operations):一系列可以按顺序链接在一起的数据处理操作,如 filtermapsorted 等。
  3. 终止操作(Terminal Operations):结束流的操作,产生最终结果或副作用,如 collectforEachfindFirst 等。

Stream API 的基本使用

创建 Stream

创建 Stream 的常见方式有:

  1. 从集合创建 Stream

    • 使用集合的 stream() 或 parallelStream() 方法创建 Stream。
  2. 从数组创建 Stream

    • 使用 Arrays.stream(array) 方法创建 Stream。
  3. 从迭代器创建 Stream

    • 使用 Stream.iterate(seed, next) 方法创建无限流。
  4. 从生成器创建 Stream

    • 使用 Stream.generate(generator) 方法创建无限流。
中间操作(Intermediate Operations)

中间操作可以链接在一起,形成流水线式的处理过程。常见的中间操作包括:

  1. filter(Predicate<T> predicate):筛选元素。
  2. map(Function<T, R> mapper):转换元素。
  3. flatMap(Function<T, Stream<R>> mapper):将嵌套的 Stream 展平。
  4. distinct():去重。
  5. sorted():排序。
  6. peek(Consumer<T> action):打印或调试输出。
终止操作(Terminal Operations)

终止操作结束 Stream,产生最终结果或副作用。常见的终止操作包括:

  1. forEach(Consumer<T> action):遍历流中的每个元素。
  2. collect(Collector<T, A, R> collector):收集流中的元素。
  3. reduce(BinaryOperator<T>):聚合流中的元素。
  4. anyMatch(Predicate<T> predicate):判断是否有元素满足条件。
  5. allMatch(Predicate<T> predicate):判断所有元素是否满足条件。
  6. noneMatch(Predicate<T> predicate):判断是否有元素不满足条件。
  7. findFirst():获取第一个元素。
  8. findAny():获取任意一个元素。
  9. count():计算元素数量。
  10. max(Comparator<T> comparator):获取最大元素。
  11. min(Comparator<T> comparator):获取最小元素。

示例代码

示例 1:基本使用
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class StreamExample {
    public static void main(String[] args) {
        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]

        // 映射平方
        List<Integer> squares = numbers.stream()
                .map(n -> n * n)
                .collect(Collectors.toList());

        System.out.println(squares); // 输出 [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

        // 排序
        List<Integer> sortedNumbers = numbers.stream()
                .sorted((a, b) -> b - a)
                .collect(Collectors.toList());

        System.out.println(sortedNumbers); // 输出 [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

        // 去重
        List<Integer> uniqueNumbers = numbers.stream()
                .distinct()
                .collect(Collectors.toList());

        System.out.println(uniqueNumbers); // 输出 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] (原列表已经是唯一的)

        // 遍历输出
        numbers.stream()
                .forEach(System.out::println);

        // 打印每个元素
        numbers.stream()
                .peek(System.out::println)
                .collect(Collectors.toList());
    }
}
示例 2:复杂操作
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class ComplexStreamExample {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David", "Eve");

        // 过滤长度大于 5 的名字,并转换成大写
        List<String> longNamesUpper = names.stream()
                .filter(name -> name.length() > 5)
                .map(String::toUpperCase)
                .collect(Collectors.toList());

        System.out.println(longNamesUpper); // 输出 [CHARLIE, DAVID]

        // 计算名字长度的总和
        int totalLength = names.stream()
                .mapToInt(String::length)
                .sum();

        System.out.println(totalLength); // 输出 23

        // 检查是否有名字长度大于 5
        boolean hasLongName = names.stream()
                .anyMatch(name -> name.length() > 5);

        System.out.println(hasLongName); // 输出 true

        // 获取最长的名字
        String longestName = names.stream()
                .max(Comparator.comparingInt(String::length))
                .orElse(null);

        System.out.println(longestName); // 输出 Charlie

        // 获取最短的名字
        String shortestName = names.stream()
                .min(Comparator.comparingInt(String::length))
                .orElse(null);

        System.out.println(shortestName); // 输出 Bob

        // 分组统计每个名字的长度出现次数
        Map<Integer, Long> lengthCount = names.stream()
                .collect(Collectors.groupingBy(String::length, Collectors.counting()));

        System.out.println(lengthCount); // 输出 {3=2, 5=1, 6=1, 7=1}

        // 归约操作
        int product = names.stream()
                .mapToInt(name -> name.length())
                .reduce(1, (a, b) -> a * b);

        System.out.println(product); // 输出 34560
    }
}

Stream API 的高级用法

1. 并行流(Parallel Streams)

并行流可以提高处理大量数据时的效率。

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

public class ParallelStreamExample {
    public static void main(String[] args) {
        Random random = new Random();
        List<Integer> numbers = IntStream.rangeClosed(1, 1000000)
                .boxed()
                .collect(Collectors.toList());

        // 使用并行流计算总和
        long parallelSum = numbers.parallelStream()
                .reduce(0L, Long::sum);

        System.out.println(parallelSum); // 输出 500000500000
    }
}
2. 构建复杂的数据结构
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class ComplexDataStructureExample {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David", "Eve");

        // 构建一个 Map,键是名字长度,值是对应的名字列表
        Map<Integer, List<String>> lengthToNames = names.stream()
                .collect(Collectors.groupingBy(String::length));

        System.out.println(lengthToNames); // 输出 {3=[Bob, Eve], 5=[Alice], 7=[Charlie], 6=[David]}
    }
}

总结

Java Stream API 提供了一种高效且易于使用的处理集合的方式。通过使用 Stream API,可以轻松实现复杂的集合操作,如过滤、映射、排序、聚合等。掌握 Stream API 的基本概念和用法后,可以更好地利用这些特性来编写高效、简洁的 Java 应用程序。

通过上述示例代码,可以看到 Stream API 如何简化集合操作,并提供更多的功能和灵活性。无论是简单的筛选和映射,还是复杂的聚合和分组,Stream API 都能够胜任。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

扬子鳄008

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值