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>() {@Overridepublic 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>() {@Overridepublic 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>() {@Overridepublic 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的规约操作的初始值是10int ans1 = list.stream().reduce(10, (a, b) -> a + b);System.out.println(ans1);// 这里结果等于:1200int 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);// 都满足: 集合中所有元素都小于6boolean 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新特性有介绍。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

算法设计与实现--贪心篇

贪心算法 贪心算法是一种在每一步选择中都采取当前状态下最优决策的算法&#xff0c;以期望能够通过一系列局部最优的选择达到全局最优。贪心算法的关键是定义好局部最优的选择&#xff0c;并且不回退&#xff0c;即一旦做出了选择&#xff0c;就不能撤销。 一般来说&#xf…

pybind11教程

pybind11教程 文章目录 pybind11教程1. pybind11简介2. cmake使用pybind11教程3. pybind11的历史 1. pybind11简介 项目的GitHub地址为&#xff1a; pybind11 pybind11 是一个轻量级的头文件库&#xff0c;用于在 Python 和 C 之间进行互操作。它允许 C 代码被 Python 调用&am…

C语言-内存分配

内存分配 1. 引入 int nums[10] {0}; //对int len 10; int nums[len] {0}; //错是因为系统的内存分配原则导致的2. 概述 在程序运行时&#xff0c;系统为了 更好的管理进程中的内存&#xff0c;所以有了 内存分配机制。 分配原则&#xff1a; 2.1 静态分配 静态分配原…

CSS——复合选择器、CSS特性、背景属性、显示模式

1、复合选择器 复合选择器&#xff1a;由两个或多个基础选择器&#xff0c;通过不同的方式组合而成。 作用&#xff1a;更准确、更高效的选择目标元素&#xff08;标签&#xff09; 1.1 后代选择器 后代选择器&#xff1a;选中某元素的后代元素 选择器写法&#xff1a;父选…

Reactor实战,创建一个简单的单线程Reactor(理解了就相当于理解了多线程的Reactor)

单线程Reactor package org.example.utils.echo.single;import java.io.IOException; import java.net.InetSocketAddress; import java.nio.channels.*; import java.util.Iterator; import java.util.Set;public class EchoServerReactor implements Runnable{Selector sele…

Android Studio build.gradle获取项目绝对路径

通过这个字段 ${project.rootProject.projectDir}";如项目根build.gradle中&#xff1a; // Top-level build file where you can add configuration options common to all sub-projects/modules.buildscript {repositories {google()mavenCentral()// jcenter() // kee…

C++基础 -35- string类

string类的格式 string a;如下图&#xff0c;使用string类比常规的字符串处理方便很多 而且需要进行的字符串处理&#xff0c;在类中都能完成 #include "iostream"using namespace std;extern "C" {#include "string.h" }int main() {//c的写…

[Firefly-Linux] RK3568 pca9555芯片驱动详解

文章目录 一、PAC9555 介绍二、ITX-3568JQ PAC9555 使用2.1 原理图2.2 设备树三、RK3568 I2C 介绍四、PAC9555 驱动4.1 介绍4.2 数据结构4.3 驱动分析一、PAC9555 介绍 PAC9555 是一种高性能、低功耗 I/O 扩展芯片,能够提供 16 个 GPIO 通道,每个通道可以单独配置为输入或输…

C语言--求一个十进制整数中1的个数

一.题目描述⭐ 求一个十进制整数中1的个数 比如&#xff1a; 输入:10201 输出&#xff1a;2 &#xff08;这个数字中1的个数是2&#xff09; 二.思路分析⭐ 数字类的问题我们可以用取模&#xff0c;或者取余运算。 首先定义一个计数器&#xff0c;用来统计1的个数。 输入数字…

Python面向对象③:封装【侯小啾python领航班系列(二十一)】

Python面向对象③【侯小啾python领航班系列(二十一)】 大家好,我是博主侯小啾, 🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ�…

关于前端学习的思考-word-wrap和word-break的区别

如上图word-wrap里面的break-word就是按照单词来换行的&#xff0c;空格在前&#xff0c;连字符在后的时候&#xff0c;按照连字符进行换行&#xff0c;那么空格和连字符哪一个拥有优先级呢&#xff1f; 连字符在前&#xff0c;空格在后的时候&#xff0c;还是按照连字符进行换…

分享66个焦点幻灯JS特效,总有一款适合您

分享66个焦点幻灯JS特效&#xff0c;总有一款适合您 66个焦点幻灯JS特效下载链接&#xff1a;https://pan.baidu.com/s/10bqe09IAZt_hbsZlXaxkxw?pwd6666 提取码&#xff1a;6666 Python采集代码下载链接&#xff1a;采集代码.zip - 蓝奏云 学习知识费力气&#xff0c;…

Linux(12):磁盘配额(Quota)与进阶文件系统管理

磁盘配额&#xff08;Quota&#xff09;的应用与实作 Quota 的一般用途&#xff1a; 针对 www server &#xff0c;例如:每个人的网页空间的容量限制&#xff1b; 针对 mail server&#xff0c;例如:每个人的邮件空间限制。 针对 file server&#xff0c;例如:每个人最大的可用…

APEX 权限的树形列表展示——基于APEX FancyTree Select

Apex-Fancy-Tree-Select git学习网页 GitHub - RonnyWeiss/Apex-Fancy-Tree-Select: Fancy Tree Plug-in for Oracle APEXhttps://github.com/RonnyWeiss/Apex-Fancy-Tree-Select 详情可见↓&#xff1a; 存档&#xff06;改造【06】Apex-Fancy-Tree-Select花式树的使用&…

synchronized的实现原理

程序员的公众号&#xff1a;源1024&#xff0c;获取更多资料&#xff0c;无加密无套路&#xff01; 最近整理了一波电子书籍资料&#xff0c;包含《Effective Java中文版 第2版》《深入JAVA虚拟机》&#xff0c;《重构改善既有代码设计》&#xff0c;《MySQL高性能-第3版》&…

基于微信小程序的高校活动系统

1 前言 1.1开发背景及意义 高校课余活动管理是中职学生素质教育的重要途径及有效方式&#xff0c;特别是对于一个院校的校园文化建设、校风学风建设和学生综合素质方面的提高至关重要t叫"。良好的学生活动组织可以更好地调动学生参与活动&#xff0c;让学生展示自己的能力…

Redis数据库

服务器结构 struct redisServer {/* General */pid_t pid; /* Main process pid. */pthread_t main_thread_id; /* Main thread id */char *configfile; /* Absolute config file path, or NULL */char *executable; /* Absolut…

Linux 编译安装colmap

COLMAP可以作为独立的app&#xff0c;通过命令行或者图形交互界面使用&#xff0c;也可以作为一个库被包含到其他源代码中。 这里记录一下编译安装colmap的过程&#xff0c;首先需要安装好CUDA&#xff0c;CUDA具体安装过程这里就不赘述了。在GitHub上下载源代码&#xff0c;我…

用Java写一个王者荣耀游戏

目录 sxt包 Background Bullet Champion ChampionDaji GameFrame GameObject Minion MinionBlue MinionRed Turret TurretBlue TurretRed beast包 Bear Beast Bird BlueBuff RedBuff Wolf Xiyi 打开Eclipse创建图片中的几个包 sxt包 Background package sxt;…

DAPP开发【06】nodejs安装与npm路径更换

windows系统在执行用户命令时顺序 windows系统在执行用户命令时&#xff0c;若用户未给出文件的绝对路径&#xff0c; 则 &#xff08;1&#xff09;首先在当前目录下寻找相应的可执行文件、批处理文件等&#xff1b; &#xff08;2&#xff09;若找不到&#xff0c;再依次在系…