JDK8中stream常用方法操作大全

 更新时间:2026年01月22日 10:54:44   作者:齐 飞  
JDK 1.8引入的Stream API是Java函数式编程的核心特性,它提供了一种高效、声明式的方式来处理集合数据,常见的终止操作包括遍历、收集、归约等,这篇文章给大家介绍JDK8中stream常用方法操作大全,感兴趣的朋友一起看看吧

前言

JDK 1.8 引入的 Stream API 是 Java 函数式编程的核心特性之一,它提供了一种高效、声明式的方式来处理集合数据(如 List、Set 等),支持链式操作、并行处理和惰性求值。

什么是 Stream?

  • Stream 不是数据结构,不存储元素,而是对数据源(如集合、数组)进行计算的一系列操作(操作数据的管道)。
  • 不可变:不会修改原始数据源。
  • 惰性求值(Lazy Evaluation):中间操作(如 filter、map)不会立即执行,只有遇到终端操作(如 collect、forEach)才会触发整个流水线。
  • 可并行处理(ParallelStream):提高大数据处理效率

Stream API 的基本概念

数据源:可以是任何实现了 Collection 接口的数据结构,或者是数组、迭代器等。
中间操作:一系列按需惰性处理数据的管道操作,如过滤、映射、排序等。
终止操作:执行计算并返回结果的操作,如收集、聚合等。一旦执行了终止操作,流就会被消费掉,不能再被重复使用。

中间操作

中间操作可以链接起来形成流水线,常见的中间操作有:

filter(Predicate):过滤元素
map(Function):映射转换
flatMap(Function):扁平化映射(将流中的每个元素转为流,再合并)
distinct():去重
sorted() / sorted(Comparator):排序
peek(Consumer):调试用,对每个元素执行操作但不改变流
limit(long):截取前 N 个
skip(long):跳过前 N 个

public static void main(String[] args) {
    List<String> list = Arrays.asList("apple", "banana", "orange", "avocado","apple");
    // 过滤
    List<String> list1 = list.stream()
            .filter(s -> s.startsWith("a"))
            .filter(s -> s.length() > 5).collect(Collectors.toList());
    System.out.println(list1);//[avocado]
    // 映射
    // 将字符串映射为对应的长度
    List<Integer> list2 = list.stream().map(String::length).collect(Collectors.toList());
    System.out.println(list2);//[5, 6, 6, 7, 5]
    // 将字符串映射为大写
    List<String> list3 = list.stream().map(String::toUpperCase).collect(Collectors.toList());
    System.out.println(list3);//[APPLE, BANANA, ORANGE, AVOCADO, APPLE]
    // 映射为指定字符串
    List<String> list4 = list.stream().map(item->item+"z").collect(Collectors.toList());
    System.out.println(list4);//[applez, bananaz, orangez, avocadoz, applez]
    // 去重
    List<String> list5 = list.stream().distinct().collect(Collectors.toList());
    System.out.println(list5);//[apple, banana, orange, avocado]
    // 排序
    List<String> list6 = list.stream().sorted().collect(Collectors.toList());
    System.out.println(list6);//[apple, apple, avocado, banana, orange]
    List<String> list7 = list.stream()
            .sorted((s1, s2) -> s2.compareTo(s1)).collect(Collectors.toList());
    System.out.println(list7);//[orange, banana, avocado, apple, apple]
    // 限制和跳过
    // 取前3个
    List<String> list8 = list.stream()
            .limit(3).collect(Collectors.toList());
    System.out.println(list8);//[apple, banana, orange]
    // 跳过第1个
    List<String> list9 = list.stream()
            .skip(1).collect(Collectors.toList());
    System.out.println(list9);//[banana, orange, avocado, apple]
}

终止操作

终止操作会触发流的执行,并且返回结果。常见的终止操作包括:

forEach(Consumer):遍历
collect(Collector):聚合成集合、字符串等(最常用)
reduce(BinaryOperator):归约(如求和、拼接)
count():元素个数
min() / max(Comparator):最值
anyMatch(Predicate) / allMatch / noneMatch:匹配检查
findFirst() / findAny():查找元素(Optional)

public static void main(String[] args) {
    List<String> list = Arrays.asList("a", "b", "c", "a");
    // 遍历
    list.stream().forEach(System.out::println);
    // 转换为数组
    String[] array = list.stream().toArray(String[]::new);
    System.out.println(array);//["a", "b", "c", "a"]
    // 聚合操作
    Optional<String> first = list.stream().findFirst();
    System.out.println(first.get());//a
    // 检查列表中是否存在以字母"a"开头的字符串
    boolean anyMatch = list.stream().anyMatch(s -> s.startsWith("a"));
    System.out.println(anyMatch);//true
    // 检查列表中所有字符串的长度是否都等于1
    boolean allMatch = list.stream().allMatch(s -> s.length() == 1);
    System.out.println(allMatch);//true
    // 检查列表中是否没有任何空字符串
    boolean noneMatch = list.stream().noneMatch(s -> s.isEmpty());
    System.out.println(noneMatch);//true
    // 计数
    long count = list.stream().count();
    System.out.println(count);//4
    List<Integer> list2 = Arrays.asList(4,5,6,7);
    // 最值
    // 获取最大值
    Integer max = list2.stream().max(Integer::compareTo).orElse(0);
    System.out.println("最大值: " + max);//最大值: 7
    int max2 = list2.stream().mapToInt(Integer::intValue).max().orElse(0);
    System.out.println("最大值: " + max2);//最大值: 7
    // 获取最小值
    Integer min = list2.stream().min(Integer::compareTo).orElse(0);
    System.out.println("最小值: " + min);//最小值: 4
    int min2 = list2.stream().mapToInt(Integer::intValue).min().orElse(0);
    System.out.println("最小值: " + min2);//最小值: 4
    // 平均值
    double avg = list2.stream().mapToInt(Integer::intValue).average().orElse(0.0);
    System.out.println("平均数: " + avg);//平均数: 5.5
    //求和
    int sum = list2.stream().mapToInt(Integer::intValue).sum();
    System.out.println("累计总和: " + sum);//累计总和: 22
    // 或者使用reduce方法计算总和
    Integer sum2 = list2.stream().reduce(Integer::sum).orElse(0);
    System.out.println("使用reduce计算总和: " + sum2);//使用reduce计算总和: 22
    //orElse()方法,主要作用是提供默认值。
    List<Integer> list3 = new ArrayList<>();
    Integer max3 = list3.stream().max(Integer::compareTo).orElse(999);
    System.out.println("最大值: " + max3);//最大值: 999
    IntSummaryStatistics stats = list2.stream()
            .collect(Collectors.summarizingInt(Integer::intValue));
    System.out.println("计数: " + stats.getCount());      // 计数: 4
    System.out.println("总和: " + stats.getSum());        // 总和: 22
    System.out.println("平均值: " + stats.getAverage());  // 平均值: 5.5
    System.out.println("最大值: " + stats.getMax());      // 最大值: 7
    System.out.println("最小值: " + stats.getMin());      // 最小值: 4
}

集合元素为类的处理

public static void main(String[] args) {
    List<Person> person = Arrays.asList(
            new Person("John", 25, "北京"),
            new Person("Jane", 30, "深圳"),
            new Person("Bob", 30, "上海"),
            new Person("Mike", 20, "深圳"),
            new Person("Lucy", 20, "深圳")
    );
    //toMap
    Map<String, Person> personMap = person.stream().collect(Collectors.toMap(Person::getName, item -> item));
    System.out.println(JSON.toJSONString(personMap));//{"Mike":{"age":20,"city":"深圳","name":"Mike"},"Bob":{"age":30,"city":"上海","name":"Bob"},"John":{"age":25,"city":"北京","name":"John"},"Lucy":{"age":20,"city":"深圳","name":"Lucy"},"Jane":{"age":30,"city":"深圳","name":"Jane"}}
    //处理key值冲突,当有冲突时保留上一个
    Map<Integer, Person> personMap2 = person.stream().collect(Collectors.toMap(Person::getAge, item -> item, (k1, k2) -> k1));
    System.out.println(JSON.toJSONString(personMap2));//{20:{"age":20,"city":"深圳","name":"Mike"},25:{"age":25,"city":"北京","name":"John"},30:{"age":30,"city":"深圳","name":"Jane"}}
    //分组
    Map<String, List<Person>> groupingMap = person.stream()
            .collect(Collectors.groupingBy(Person::getCity));
    System.out.println(JSON.toJSONString(groupingMap));//{"上海":[{"age":30,"city":"上海","name":"Bob"}],"深圳":[{"age":30,"city":"深圳","name":"Jane"},{"age":20,"city":"深圳","name":"Mike"},{"age":20,"city":"深圳","name":"Lucy"}],"北京":[{"age":25,"city":"北京","name":"John"}]}
    // 多级分组
    Map<String, Map<Integer, List<Person>>> multiGroupingMap = person.stream()
            .collect(Collectors.groupingBy(
                    Person::getCity,
                    Collectors.groupingBy(Person::getAge)
            ));
    System.out.println(JSON.toJSONString(multiGroupingMap));//{"上海":{30:[{"age":30,"city":"上海","name":"Bob"}]},"深圳":{20:[{"age":20,"city":"深圳","name":"Mike"},{"age":20,"city":"深圳","name":"Lucy"}],30:[{"age":30,"city":"深圳","name":"Jane"}]},"北京":{25:[{"age":25,"city":"北京","name":"John"}]}}
    // 分区(分成true/false两组)
    Map<Boolean, List<Person>> partition = person.stream()
            .collect(Collectors.partitioningBy(p -> p.getAge() > 25));
    System.out.println(JSON.toJSONString(partition));//{false:[{"age":25,"city":"北京","name":"John"},{"age":20,"city":"深圳","name":"Mike"},{"age":20,"city":"深圳","name":"Lucy"}],true:[{"age":30,"city":"深圳","name":"Jane"},{"age":30,"city":"上海","name":"Bob"}]}
}
// 静态内部类
static class Person {
    private String name;
    private Integer age;
    private String city;
    public Person(String name, Integer age, String city) {
        this.name = name;
        this.age = age;
        this.city = city;
    }
    public String getName() { return name; }
    public Integer getAge() { return age; }
    public String getCity() { return city; }
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", city='" + city + '\'' +
                '}';
    }
}

并行流

public static void main(String[] args) {
    List<Person> list = new ArrayList<>();
    for (int i = 0; i < 50000; i++) {
        int j = i % 30;
        Person person = new Person("用户"+i, j, "test"+i);
        list.add(person);
    }
    long startTime = System.currentTimeMillis();
    List<Person> test1 = list.stream().filter(item -> item.getAge() > 20).map(item -> {
        item.setAge(item.getAge() * 2);
        return item;
    }).collect(Collectors.toList());
    long endTime = System.currentTimeMillis();
    System.out.println("执行时间: " + (endTime - startTime) + " 毫秒");//执行时间: 63 毫秒
    long startTime2 = System.currentTimeMillis();
    List<Person> test2 = list.parallelStream().filter(item -> item.getAge() > 20).map(item -> {
        item.setAge(item.getAge() * 2);
        return item;
    }).collect(Collectors.toList());
    long endTime2 = System.currentTimeMillis();
    System.out.println("执行时间: " + (endTime2 - startTime2) + " 毫秒");//执行时间: 19 毫秒
}
// 静态内部类
static class Person {
    private String name;
    private Integer age;
    private String city;
    public Person(String name, Integer age, String city) {
        this.name = name;
        this.age = age;
        this.city = city;
    }
    public String getName() { return name; }
    public Integer getAge() { return age; }
    public String getCity() { return city; }
    public void setName(String name) {
        this.name = name;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    public void setCity(String city) {
        this.city = city;
    }
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", city='" + city + '\'' +
                '}';
    }
}

到此这篇关于JDK8中stream中常用方法的文章就介绍到这了,更多相关jdk8 stream方法内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Spring启动过程中实例化部分代码的分析之Bean的推断构造方法

    Spring启动过程中实例化部分代码的分析之Bean的推断构造方法

    这篇文章主要介绍了Spring启动过程中实例化部分代码的分析之Bean的推断构造方法,实例化这一步便是在doCreateBean方法的 instanceWrapper = createBeanInstance(beanName, mbd, args);这段代码中,本文通过实例代码给大家介绍的非常详细,需要的朋友参考下吧
    2022-09-09
  • Java中ArrayList的使用详细介绍

    Java中ArrayList的使用详细介绍

    这篇文章主要介绍了Java中ArrayList的使用,本文给大家详细讲述该相关的知识点,并且会通过大量的案例加以说明,需要的朋友可以参考一下
    2022-04-04
  • Java探索之string字符串的应用代码示例

    Java探索之string字符串的应用代码示例

    这篇文章主要介绍了Java探索之string字符串的应用代码示例,具有一定参考价值,需要的朋友可以了解下。
    2017-10-10
  • SpringSecurity抛出异常但AccessDeniedHandler不生效的解决

    SpringSecurity抛出异常但AccessDeniedHandler不生效的解决

    本文主要介绍了SpringSecurity抛出异常但AccessDeniedHandler不生效的解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-01-01
  • Java中枚举的实现原理介绍

    Java中枚举的实现原理介绍

    大家好,本篇文章主要讲的是Java中枚举的实现原理介绍,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次浏览
    2021-12-12
  • springboot+mybatis-plus基于拦截器实现分表的示例代码

    springboot+mybatis-plus基于拦截器实现分表的示例代码

    本文主要介绍了springboot+mybatis-plus基于拦截器实现分表,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-11-11
  • druid的borrow行为方法源码解析

    druid的borrow行为方法源码解析

    这篇文章主要为大家介绍了druid的borrow行为方法源码解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • Spring Batch轻量级批处理框架实战

    Spring Batch轻量级批处理框架实战

    本文主要介绍了Spring Batch轻量级批处理框架实战,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-10-10
  • 浅谈Java内存模型之happens-before

    浅谈Java内存模型之happens-before

    于存在线程本地内存和主内存的原因,再加上重排序,会导致多线程环境下存在可见性的问题。那么我们正确使用同步、锁的情况下,线程A修改了变量a何时对线程B可见?下面小编来简单介绍下
    2019-05-05
  • springboot新建项目pom.xml文件第一行报错的解决

    springboot新建项目pom.xml文件第一行报错的解决

    这篇文章主要介绍了springboot新建项目pom.xml文件第一行报错的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-01-01

最新评论