Stream API 方法使用总结

文章目录

    • 1.1、Stream介绍
    • 1.2、Stream创建对象
      • (1)empty()方法
      • (2)of()方法
      • (3)Arrays.stream()方法
      • (4)list.stream()方法
    • 1.3、Stream中间方法
      • (1)filter()方法
      • (2)map()方法
      • (3)flatMap()方法
      • (4)limit()方法
      • (5)skip()方法
      • (6)sorted()方法
      • (7)distinct()方法
      • (8)peek()方法
    • 1.4、Stream终端方法
      • (1)min()方法
      • (2)max()方法
      • (3)count()方法
      • (4)reduce()方法
      • (5)anyMatch()方法
      • (6)allMatch()方法
      • (7)noneMatch()方法
      • (8)findFirst()方法
      • (9)findAny()方法
      • (10)forEach()方法
      • (11)collect()方法

1.1、Stream介绍

Stream是JDK1.8新增的一个特性,它是一个位于【java.util.stream】包下面的接口,接口中定义了用于操作数据的公共方法,Stream被称作:【流】,它的意图就是可以按照流的方式对数据进行一些加工处理,实际开发里面最常见的就是操作集合数据,通过Stream API可以编写很少的代码就完成某一个功能,相比于传统的集合处理方式,Stream API显示更加的优雅、高效。

Java中可以将Stream API方法大致分为两类,分别是:【中间方法】和【终端方法】。

  • 中间方法:在Stream流被消费之前,对Stream流中的数据进行一些加工处理,然后返回加工处理之后的新的Stream流。
  • 终端方法:Stream流经过中间方法的加工处理之后,最终是需要被消费的,调用终端方法之后,这个Stream流就结束了,之后就不能够在使用这个Stream流对象。

Stream流处理大致流程图:

在这里插入图片描述

下面详细介绍一下Stream API的常见方法。

1.2、Stream创建对象

Java中主要有下面四种方法创建一个Stream对象,分别如下所示:

  • 第一种:使用Stream提供的empty()方法。
  • 第二种:使用Stream提供的of()方法。
  • 第三种:使用Arrays.stream()数组工具类提供的方法。
  • 第四种:使用集合对象的stream()方法(这种方式在实际开发里面最常用)。

(1)empty()方法

Stream接口中提供了一个empty()方法,该方法用于创建一个空的Stream对象,基本上不会用这个方法吧,反正我是没用过-

public class StreamDemo {
    public static void main(String[] args) {
        // 创建空的 Stream 对象
        Stream<Object> empty = Stream.empty();
    }
}

(2)of()方法

Stream接口中提供了两个of()方法,of()方法可以将传入的数据转换为一个Stream对象返回。

public class StreamDemo {
    public static void main(String[] args) {
        // 创建 Stream 对象
        Stream<String> stream = Stream.of("123");
        // 可变参数
        Stream<Integer> stream1 = Stream.of(1, 2, 3, 4);
    }
}

(3)Arrays.stream()方法

Arrays数组工具类中提供了一个stream()方法,该方法可以将数组转换为Stream流对象。

public class StreamDemo {
    public static void main(String[] args) {
        // 创建 Stream 对象
        int[] arr = new int[] {1, 2, 3, 4, 5};
        IntStream stream = Arrays.stream(arr);
    }
}

(4)list.stream()方法

Java集合类中提供了一个stream()方法,作用也是将Collection集合数据转换为Stream流对象。

public class StreamDemo {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("111");
        list.add("222");
        list.add("333");
        // 创建 Stream 对象
        Stream<String> stream = list.stream();
    }
}

注意:只要是Collection集合类,它都具有stream()方法。并且这个也是最常用的方法,因为实际开发里面,集合是最常见的操作对象。

1.3、Stream中间方法

Stream中间方法是对Stream流中数据进行一些加工处理的,中间方法的返回值都是一个新的Stream流对象,这个Stream流对象就是加工处理之后的新对象。

(1)filter()方法

filter()方法用于过滤Stream流中的数据,该方法需要传递一个【Predicate】对象(一个函数式接口),可以采用lambada表达式编写过滤条件。

public class StreamDemo {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("111");
        list.add("222");
        list.add("333");
        // 创建 Stream 对象
        Stream<String> stream = list.stream();
        // 过滤方法: 过滤出集合中不等于 222 的数据
        Stream<String> stream1 = stream.filter(item -> !item.equals("222"));
    }
}

(2)map()方法

map()方法主要作用就是将一个Stream流映射成一个新的Stream流,map方法使用最为频繁,比如:从集合中提取某个对象的某个属性,将其组成新的一个集合,下面看下两种实现方式。

  • 没有使用Stream.map()方法的代码。
public static void main(String[] args) {
    List<User> userList = getUserList();
    // 从集合中提取 姓名
    List<String> nameList = new ArrayList<>();
    for (int i = 0; i < userList.size(); i++) {
        nameList.add(userList.get(i).getName());
    }
}
  • 采用Stream.map()方法的代码。
public static void main(String[] args) {
    List<User> userList = getUserList();
    // 从集合中提取 姓名
    List<String> nameList = userList.stream().map(item -> item.getName()).collect(Collectors.toList());
}

对比上面两种方式,可以看到,采用Stream API编写的代码是多么的优雅,并且代码也简化了很多。

(3)flatMap()方法

flatMap()方法和map()方法的作用是类似的,都是用于映射Stream流的,只不过flatMap()方法可以将多个不同的Stream流映射为一个Stream流对象,flat表示【扁平化】的意思,就好比将多行数据合并成一行数据,这个就是扁平化。

public class StreamDemo {
    public static List<List<User>> getUserList() {
        List<List<User>> ans = new ArrayList<>();
        List<User> list = new ArrayList<>();
        list.add(new User(333, "name_003", "pass_003"));
        list.add(new User(111, "name_001", "pass_001"));
        list.add(new User(444, "name_004", "pass_004"));
        ans.add(list);
        List<User> list2 = new ArrayList<>();
        list2.add(new User(222, "name_002", "pass_002"));
        ans.add(list2);
        return ans;
    }
    public static void main(String[] args) {
        List<List<User>> userList = getUserList();
        System.out.println(userList);
        // 将集合中的集合,转换为一个集合
        List<User> ansList = userList.stream().flatMap(item -> item.stream()).collect(Collectors.toList());
        System.out.println(ansList);
    }
}

上面案例中,由于集合里面的元素又是集合,为了将整个集合变成一个集合,通过Stream中的flatMap()方法,将多个Stream流映射成一个Stream对象。

(4)limit()方法

limit()方法作用是限定数据的条数,比如:集合中有100条数据,通过limit()方法可以只获取10条数据。

public static void main(String[] args) {
    List<String> list = new ArrayList<>();
    list.add("111");
    list.add("222");
    list.add("333");
    list.add("444");
    list.add("555");
    // 限定5条数据
    Stream<String> stream = list.stream().limit(5);
}

(5)skip()方法

skip()方法作用是:跳过多少条数据,然后在开始处理数据。比如:现在有100条数据,前10条数据是不需要的,从第11条数据开始进行处理,这个时候就可以通过skip()方法跳过前10条数据进行处理。

public static void main(String[] args) {
    List<String> list = new ArrayList<>();
    list.add("111");
    list.add("222");
    list.add("333");
    list.add("444");
    list.add("555");
    // 跳过前 2 条数据
    Stream<String> skip = list.stream().skip(2);
    // 打印结果
    skip.forEach(System.out::println);
}

打印结果如下所示:

在这里插入图片描述

(6)sorted()方法

sorted()方法作用是将数据进行排序,sorted()有两个方法,一个是无参的sorted()方法,另一个是有参数的sorted(Comparator)方法。

  • sorted()无参方法,默认按照自然排序规则,升序排序所有数据,即:数值类按照从小到大排序,字符串按照字典序排序。
public static void main(String[] args) {
    List<String> list = new ArrayList<>();
    list.add("333");
    list.add("111");
    list.add("444");
    list.add("222");
    list.add("555");
 
    System.out.println("排序前: ");
    list.forEach(item -> System.out.print(item + " "));
    System.out.println();
 
    // 排序
    Stream<String> sorted = list.stream().sorted();
    System.out.println("排序后: ");
    sorted.forEach(item -> System.out.print(item + " "));
}

运行结果如下所示:

在这里插入图片描述

  • sorted()有参方法,自定义排序比较器,自定义排序规则。
public class StreamDemo {
    public static List<User> getUserList() {
        List<User> list = new ArrayList<>();
        list.add(new User(333, "name_003", "pass_003"));
        list.add(new User(111, "name_001", "pass_001"));
        list.add(new User(444, "name_004", "pass_004"));
        list.add(new User(222, "name_002", "pass_002"));
        return list;
    }
    public static void main(String[] args) {
        List<User> userList = getUserList();
        System.out.println("排序前: ");
        userList.forEach(System.out::println);
 
        // 自定义排序
        Stream<User> sorted = userList.stream().sorted(new Comparator<User>() {
            @Override
            public int compare(User o1, User o2) {
                return o1.getId() - o2.getId();
            }
        });
 
        System.out.println("排序后: ");
        sorted.forEach(System.out::println);
    }
}

运行结果如下所示:

在这里插入图片描述

(7)distinct()方法

distinct()方法作用是将数据中的重复数据去重操作,只保留一条数据。

public static void main(String[] args) {
    List<String> list = new ArrayList<>();
    list.add("111");
    list.add("222");
    list.add("333");
    list.add("444");
	// 重复数据
    list.add("555");
    list.add("555");
    // 去重
    Stream<String> distinct = list.stream().distinct();
    // 打印结果
    distinct.forEach(System.out::println);
}

打印结果如下所示:

在这里插入图片描述

(8)peek()方法

peek()方法接收一个Consumer消费者对象,消费者可以对流中的数据进行修改操作或者访问操作。

public class StreamDemo {
    public static List<User> getUserList() {
        List<User> list = new ArrayList<>();
        list.add(new User(333, "name_003", "pass_003"));
        list.add(new User(111, "name_001", "pass_001"));
        list.add(new User(444, "name_004", "pass_004"));
        list.add(new User(222, "name_002", "pass_002"));
        return list;
    }
    public static void main(String[] args) {
        List<User> userList = getUserList();
        // peek 修改数据
        Stream<User> peek = userList.stream().peek(item -> item.setName("demo_peek"));
        peek.forEach(System.out::println);
    }
}

注意:Stream中间方法的执行操作并不会立即生效,只有调用终端方法之后,中间方法的执行效果才会生效。

1.4、Stream终端方法

终端方法是将Stream流消费之后,并且最终会得到一个结果,常见的终端方法下面这些。

(1)min()方法

min()方法主要作用:从数据流中计算出最小值元素。min()方法需要提供一个Comparator比较器对象,通过比较器器对象的比较规则,找出最小值元素。

注意:min()方法不是说找出最小的元素,它是根据你指定的比较器规则找出最小元素。

比如下面这个例子,集合元素是【1,2,3,4,5】,但是比较器规则是后一个元素减去前一个元素。

public static void main(String[] args) {
    List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
    Optional<Integer> min = list.stream().min(new Comparator<Integer>() {
        @Override
        public int compare(Integer o1, Integer o2) {
            return o2 - o1;
        }
    });
    Integer ans = min.get();
    System.out.println(ans);
}

上面输出结果是:【5】。

(2)max()方法

max()方法作用:从数据流中计算出最小值元素。参数和min()方法是相同的。

public static void main(String[] args) {
    List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
    Optional<Integer> max = list.stream().max(new Comparator<Integer>() {
        @Override
        public int compare(Integer o1, Integer o2) {
            return o2 - o1;
        }
    });
    Integer ans = max.get();
    System.out.println(ans);
}

上面输出结果是:【1】。

(3)count()方法

count()方法作用:统计Stream流中数据元素个数,返回值是long类型。

public static void main(String[] args) {
    List<Integer> list = Arrays.asList(2, 1, 5, 4, 3);
    // 计算个数
    long count = list.stream().count();
    System.out.println(count);
}

(4)reduce()方法

reduce()方法作用:将stream流中数据进行规约操作,最终得到一个结果。这里的规约就类似于迭代,比如:要计算stream流中所有数据的和,那就可以使用reduce()方法进行规约计算。

public static void main(String[] args) {
    List<Integer> list = Arrays.asList(2, 1, 5, 4, 3);
    // 规约操作
    Optional<Integer> ans = list.stream().reduce((a, b) -> a + b);
    System.out.println(ans.get());
    // 指定初始值:
    // 这里指定第一个参数值是10,也就是reduce的规约操作的初始值是10
    int ans1 = list.stream().reduce(10, (a, b) -> a + b);
    System.out.println(ans1);
 
    // 这里结果等于:1200
    int ans2 = list.stream().reduce(10, (a, b) -> a * b);
    System.out.println(ans2);
}

运行结果如下所示:

在这里插入图片描述

reduce()规约操作分析:

在这里插入图片描述

(5)anyMatch()方法

anyMatch()方法作用:只要stream数据流中 【存在一个满足匹配】 条件的数据,那么方法就会返回true,否则返回false。

(6)allMatch()方法

allMatch()方法作用:只有当stream数据流中的所有数据,【都满足匹配】 条件的数据,那么方法才会返回true,否则返回false。

(7)noneMatch()方法

allMatch()方法作用:只有当stream数据流中的所有数据,【都不满足匹配】 条件的数据,那么方法才会返回true,否则返回false。

public static void main(String[] args) {
    List<Integer> list = Arrays.asList(2, 1, 5, 4, 3);
    // 满足一个: 集合中有一个元素是大于4的
    boolean match = list.stream().anyMatch(item -> item > 4);
    System.out.println(match);
    // 都满足: 集合中所有元素都小于6
    boolean match1 = list.stream().allMatch(item -> item < 6);
    System.out.println(match1);
    // 都不满足: 集合中不存在大于 6 的元素
    boolean match2 = list.stream().noneMatch(item -> item > 6);
    System.out.println(match2);
}

(8)findFirst()方法

findFirst()方法作用:从stream流中获取第一条数据。

public class StreamDemo {
    public static List<User> getUserList() {
        List<User> list = new ArrayList<>();
        list.add(new User(333, "name_003", "pass_003"));
        list.add(new User(111, "name_001", "pass_001"));
        list.add(new User(444, "name_004", "pass_004"));
        list.add(new User(222, "name_002", "pass_002"));
        return list;
    }
    public static void main(String[] args) {
        List<User> userList = getUserList();
        // 获取第一条数据
        Optional<User> first = userList.stream().findFirst();
        if (first.isPresent()) {
            System.out.println(first.get());
        }
    }
}

(9)findAny()方法

findAny()方法作用:从stream数据流中随机返回一条数据。

(10)forEach()方法

forEach()方法作用:遍历stream流中的数据元素。

public static void main(String[] args) {
    List<String> list = new ArrayList<>();
    list.add("333");
    list.add("111");
    list.add("444");
    list.add("222");
    list.add("555");
    list.stream().forEach(item -> {
        System.out.println(item);
    });
}

(11)collect()方法

collect()方法作用:用于将中间方法处理的stream流收集为一个结果,常见的如:List、Set、Map等等。

public class StreamDemo {
    public static List<User> getUserList() {
        List<User> list = new ArrayList<>();
        list.add(new User(333, "name_003", "pass_003"));
        list.add(new User(111, "name_001", "pass_001"));
        list.add(new User(444, "name_004", "pass_004"));
        list.add(new User(222, "name_002", "pass_002"));
        return list;
    }
    public static void main(String[] args) {
        List<User> userList = getUserList();
        List<String> ansList = userList.stream().map(User::getName).collect(Collectors.toList());
        System.out.println(ansList);
    }
}

这个collect()方法更多的用法上一篇文章Java8新特性有介绍。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/214832.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot之自定义Starter

目录 一、自己的理解 1. 理解一 2. 理解二 二、自定义starter&#xff08;重点&#xff09; 三、以mybatis-spring-boot-starter为例进行分析 1. 写好自己的自动配置类逻辑 2. 创建自己的starter项目并引入自动配置类项目的依赖 3. 在其它项目中使用自定义的starter 一…

如何开启Windows Server 2016 远端桌面

使用GUI 设定 服务器管理器–> 本地服务器–> 远端桌面 启用远端桌面 远端–> 允许远端连线至此电脑 会提示防火墙设定跟电源设定 防火墙之前已经关闭了 完成

设计基于STM32的温度传感器实时数据采集和显示系统

温度传感器作为常见的传感器之一&#xff0c;被广泛应用于各种领域&#xff0c;如工业自动化、家电控制等。为了实时监测和控制温度&#xff0c;设计一个基于STM32的温度传感器实时数据采集和显示系统是很有必要的。本文将详细介绍如何设计这样一个系统&#xff0c;并提供相应的…

nodejs微信小程序+python+PHP健身房信息管理系统的设计与实现-计算机毕业设计推荐

目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 express框架介绍 6 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性&#xff1a;…

Gitee拉取代码报错You hasn‘t joined this enterprise! fatal unable to access

文章目录 一、问题二、解决2.1、进入**控制面板**2.2、进入**用户账户**2.3、进入**管理Windows凭据**2.4、**普通凭据**2.4.1、添加2.4.2、编辑 2.5、重新拉取|推送代码 三、最后 一、问题 Gitee拉取仓库代码的时候报错You hasnt joined this enterprise! fatal unable to ac…

二十五、DSL查询文档(全文检索查询、精确查询、地理查询、复合查询)

目录 一、全文检索查询 1、match查询 语法: 2、multi_match查询 语法: 3、match和mult_match的区别 二、精确查询 1、term查询&#xff1a; 语法&#xff1a; 2、range查询&#xff1a;&#xff08;范围查询&#xff09; 语法&#xff1a; 三、地理查询 1、geo_bou…

SSM新闻发布管理系统

SSM毕设分享 序号1&#xff1a;SSM新闻发布管理系统 1 项目简介 Hi&#xff0c;各位同学好&#xff0c;这里是郑师兄&#xff01; 今天向大家分享一个毕业设计项目作品【SSM新闻发布管理系统】 师兄根据实现的难度和等级对项目进行评分(最低0分&#xff0c;满分5分) 难度系数…

【算法】单调栈题单——矩阵系列⭐

文章目录 题目列表84. 柱状图中最大的矩形&#xff08;单调栈找左右两边第一个更低的位置&#xff09;85. 最大矩形⭐⭐⭐⭐⭐解法1——使用柱状图的优化暴力方法解法2——单调栈 &#xff1a;归因到 84. 柱状图中最大的矩形 &#x1f402; 1504. 统计全 1 子矩形⭐解法1——枚…

Java 不要在父类的构造方法里面调用可以被子类重写的方法

不要在父类的构造方法(代码块)里面调用可以被子类重写的方法 我们从第一天学习Java开始&#xff0c;就对Java的类初始化顺序牢记于心。但是在实际开发过程中&#xff0c;似乎很难能接触这一部分的应用。在这之前&#xff0c;我也认为它只是面试中八股文而已&#xff0c;直到最…

The Big IAM Challenge 云安全 CTF 挑战赛

The Big IAM Challenge 云安全 CTF 挑战赛 今天&#xff0c;我们来做一下有关于云安全 的CTF 挑战赛 The Big IAM Challenge,旨在让白帽子识别和利用 IAM错误配置&#xff0c;并从现实场景中学习&#xff0c;从而更好的认识和了解IAM相关的风险。比赛包括6个场景&#xff0c;每…

Zotero 安装及常用插件设置指南

Zotero 安装及常用插件设置指南 本指南旨在帮助用户安装并配置 Zotero。通过本教程&#xff0c;您将能够实现以下功能&#xff1a; 界面语言设置为中文使用颜色标签来区分不同阅读状态的文献重要文献标记显示影响因子、JCP和中科院分区翻译插件Sci-Hub 集成 安装和设置步骤…

leetCode 90.子集 II + 回溯算法 + 图解 + 笔记

给你一个整数数组 nums &#xff0c;其中可能包含重复元素&#xff0c;请你返回该数组所有可能的子集&#xff08;幂集&#xff09;。 解集 不能 包含重复的子集。返回的解集中&#xff0c;子集可以按 任意顺序 排列 示例 1&#xff1a; 输入&#xff1a;nums [1,2,2] 输出…

基于CNN对彩色图像数据集CIFAR-10实现图像分类--keras框架实现

项目地址&#xff08;kaggle&#xff09;&#xff1a;基于CNN对彩色图像数据集CIFAR-10实现图像分类--keras | Kaggle 项目地址&#xff08;Colab&#xff09;&#xff1a;https://colab.research.google.com/drive/1gjzglPBfQKuhfyT3RlltCLUPgfccT_G9 导入依赖 在tensorflow…

第一百八十八回 分享三个使用TextField的细节

文章目录 1. 概念介绍2. 使用方法2.1 修改组件的填充颜色2.2 修改组件的高度2.3 给组件添加圆角3. 示例代码4. 内容总结我们在上一章回中介绍了"DropdownButton组件"相关的内容,本章回中将介绍**TextField组件的细节.**闲话休提,让我们一起Talk Flutter吧。 1. 概念…

EasyRecovery易恢复2024最新免费版电脑数据恢复软件功能介绍

EasyRecovery从&#xff08;易恢复2024&#xff09;支持恢复不同存储介质数据&#xff0c;在Windows中恢复受损和删除文件,以及能检索数据格式化或损坏卷&#xff0c;甚至还可以从初始化磁盘。同时&#xff0c;你只需要最简单的操作就可以恢复数据文件&#xff0c;如&#xff1…

YITH Product Shipping for WooCommerce商城产品配送运输插件

点击访问原文 YITH Product Shipping for WooCommerce商城产品配送运输插件 - 易服客工作室 YITH Product Shipping for WooCommerce商城产品配送运输插件根据商店的每个产品处理不同的运费&#xff0c;例如您可以为每个州、地区或城市设置不同的费用。 根据店铺的单品处理不…

搭建 ebpf 开发测试环境

0 内容说明 这部分主要讲述了如何通过官网学习ebpf&#xff0c;以及如何搭建自己的ebpf开发测试环境&#xff0c;主要是需要安装哪些工具链。 1 ebpf在线学习 ebpf官网中提供了一个快速在线学习ebpf的路径&#xff0c;在这个学习平台中一共有两项学习内容&#xff0c;一个是…

在Spring Boot中隔离@Async异步任务的线程池

在异步任务执行的时候&#xff0c;我们知道其背后都有一个线程池来执行任务&#xff0c;但是为了控制异步任务的并发不影响到应用的正常运作&#xff0c;我们需要对线程池做好相关的配置&#xff0c;以防资源过度使用。这个时候我们就考虑将线程池进行隔离了。 那么我们为啥要…

高校人员信息管理系统C++

代码&#xff1a;https://mbd.pub/o/bread/ZZeZk5lx 一、基本内容论述 1、问题描述 某高校有四类员工&#xff1a;教师、实验员、行政人员、教师兼行政人员&#xff1b;共有的信息包括&#xff1a;编号、姓名、性别、年龄等。其中&#xff0c;教师还包含的信息有&#xff1a;所…

2023年GopherChina大会-核心PPT资料下载

一、峰会简介 自 Go 语言诞生以来&#xff0c;中国便是其应用最早和最广的国家之一&#xff0c;根据 Jetbrains 在 2021 年初做的调查报告&#xff0c;总体来说目前大概有 110 万专业的开发者 选择 Go 作为其主要开发语言。就其全球分布而言, 居住在亚洲的开发者最多&#xff…