当前位置: 首页 > news >正文

Stream流学习笔记

Stream流

    • 创建流
    • 中间操作
      • 1、filter
      • 2、map
      • 3、distinct
      • 4、sorted
      • 5、limit
      • 6、skip
      • 7、flatMap
    • 终结操作
      • 1、forEach
      • 2、count
      • 3、max&min
      • 4、collect
      • 5、查找与匹配

创建流

单例集合:集合对象.stream()

List<Integer> list = new ArrayList<>();
Stream<Integer> stream = list.stream();

数组:Arrays.stream(数组) 或 Stream.of(数组) 来创建

Integer[] arr = {1,2,3,4};
Stream<Integer> stream1 = Arrays.stream(arr);
Stream<Integer> stream2 = Stream.of(arr);

双例集合:转换成单例集合后再创建

Map<String, String> map = new HashMap<>();
Stream<Map.Entry<String, String>> stream3 = map.entrySet().stream();

中间操作

1、filter

对流中的元素进行条件过滤,符合过滤条件的才能继续留在流中。

public static void test() {List<Author> authors = getAuthors();authors.stream().filter(author -> author.getAge() > 18) //中间操作.forEach(author -> System.out.println(author)); //终结操作
}

2、map

可以把流中的元素进行计算或转换。

转换:

public static void test() {List<Author> authors = getAuthors();//泛型中,第一个参数为方法的参数类型,第二个参数为方法的返回值类型authors.stream().map(author -> author.getName()).forEach(name -> System.out.println(name));
}

3、distinct

去除流中的重复元素。

注意:distinct方法是依赖Object的equals方法来判断是否是相同对象,所以需要重写equals方法。

4、sorted

对流中的元素进行排序。

方式一:调用sorted()空参方法
在比较的实体类上要实现Comparable接口,不然会报类型不匹配的异常。

image-20240212122159278

public static void test2() {List<Author> authors = getAuthors();authors.stream().distinct().sorted().forEach(author -> System.out.println(author.getAge()));
}

方式二:在sorted方法中实现Comparator接口

public static void test2() {List<Author> authors = getAuthors();authors.stream().distinct().sorted(new Comparator<Author>() {@Overridepublic int compare(Author o1, Author o2) {return o1.getAge()-o2.getAge();}}).forEach(author -> System.out.println(author.getAge()));
}

优化

public static void test2() {List<Author> authors = getAuthors();authors.stream().distinct().sorted((o1, o2) -> o1.getAge()-o2.getAge()).forEach(author -> System.out.println(author.getAge()));
}

5、limit

可以设置流的最大长度,超出的部分将被抛弃。

//对流中的元素按照年龄进行降序排序,并且要求不能有重复元素,打印其中年龄最大的两个作家。
public static void test2() {List<Author> authors = getAuthors();authors.stream().distinct().sorted((o1, o2) -> o2.getAge()-o1.getAge()).limit(2).forEach(author -> System.out.println(author.getName()));
}

6、skip

跳过流中的前n个元素,返回剩下的元素。

7、flatMap

map只能把一个对象转换成另一个对象来作为流中的元素。而flatMap可以把一个对象转换成多个对象作为流中的元素。

案例1:打印所有书籍的名字,要求对重复的元素进行去重。
map方式:Author对象的books属性是集合类型,使用原来map转换对象,要使用嵌套循环进行打印。

public static void test2() {List<Author> authors = getAuthors();authors.stream().map(author -> author.getBooks()).forEach(books -> {for (Book book : books) {System.out.println(book.getName());}});
}

flatMap方式:

public static void test2() {List<Author> authors = getAuthors();authors.stream().flatMap(author -> author.getBooks().stream()).forEach(book -> System.out.println(book.getName()));
}

案例二:打印现有数据的所有分类,要求对分类进行去重。不能出现这种格式:哲学,爱情,要将它们拆开输出。

public static void test3() {List<Author> authors = getAuthors();authors.stream().flatMap(author -> author.getBooks().stream()).distinct().flatMap(book -> Arrays.stream(book.getCategory().split(","))).distinct().forEach(category -> System.out.println(category));
}

终结操作

1、forEach

对流中的元素进行遍历操作,我们通过传入的参数去指定对遍历到的元素进行什么具体操作。

2、count

获取当前流中元素的个数。

//打印这些作家的所出书籍的数量
public static void test4() {List<Author> authors = getAuthors();long count = authors.stream().flatMap(author -> author.getBooks().stream()).distinct().count();System.out.println(count);
}

3、max&min

获取流中的最值

//分别获取这些作家所出书籍的最高分和最低分
public static void test4() {List<Author> authors = getAuthors();Optional<Integer> max = authors.stream().flatMap(author -> author.getBooks().stream()).map(book -> book.getScore()).max((o1, o2) -> o1 - o2);Optional<Integer> min = authors.stream().flatMap(author -> author.getBooks().stream()).map(book -> book.getScore()).min(((o1, o2) -> o1 - o2));System.out.println(max.get());System.out.println(min.get());
}

4、collect

把当前流转换成一个集合。

list集合

//获取一个存放所有作者名字的list集合
public static void test5() {List<Author> authors = getAuthors();List<String> nameList = authors.stream().map(author -> author.getName()).collect(Collectors.toList());System.out.println(nameList);
}

set集合

//获取一个存放所有作者名字的set集合
public static void test5() {List<Author> authors = getAuthors();Set<String> nameList = authors.stream().map(author -> author.getName()).collect(Collectors.toSet());System.out.println(nameList);
}

map集合

//获取一个Map集合,map的key为作者名,value为List<Book>
public static void test5() {List<Author> authors = getAuthors();Map<String, List<Book>> map = authors.stream().distinct().collect(Collectors.toMap(author -> author.getName(), author -> author.getBooks()));System.out.println(map);
}

5、查找与匹配

(1)anyMatch:判断是否有任意符合匹配条件的元素,结果为boolean类型。

//判断是否有作家年龄在18以上
public static void test6() {List<Author> authors = getAuthors();boolean flag = authors.stream().anyMatch(author -> author.getAge() > 18);System.out.println(flag);
}

(2)allMatch:判断是否都符合条件,如果都符合返回true,否则返回false

//判断是否所有作家年龄在18以上
public static void test6() {List<Author> authors = getAuthors();boolean flag = authors.stream().allMatch(author -> author.getAge() > 18);System.out.println(flag);
}

(3)noneMatch:判断流中的元素是否都不符合匹配条件,如果都不符合结果为true,否则结果为false。

(4)findAny:获取流中的任意一个元素。该方法没有办法保证获取到的一定是流中的第一个元素。

//获取任意一个年龄大于18的作家,如果存在就输出他的名字
public static void test7() {List<Author> authors = getAuthors();Optional<Author> any = authors.stream().filter(author -> author.getAge() > 18).findAny();//如果这个Optional中有元素,则执行方法,没有就不执行any.ifPresent(author -> System.out.println(author.getName()));
}

(5)findFirst:获取流中的第一个元素。

//获取一个年龄最小的作家,并输出他的姓名
public static void test7() {List<Author> authors = getAuthors();Optional<Author> any = authors.stream().sorted((o1, o2) -> o1.getAge()-o2.getAge()).findFirst();any.ifPresent(author -> System.out.println(author.getName()));
}

(6)reduce归并
对流中的数据按照你指定的计算方式计算出一个结果。(缩减操作)

reduce的作用是把stream中的元素给组合起来。我们可以传入一个初始值,它会按照我们的计算方式依次拿流中的元素和初始化值进行计算,计算结果再和后面的元素计算。

它内部的计算方式如下:

T result = identity;
for (T element : this stream)result = accumulator.apply(result, element)
return result;

其中identity就是我们可以通过方法参数传入的初始值,accumulator的apply具体进行什么计算也是我们通过方法参数来确定的。

案例1:使用reduce求所有作者年龄的和

public static void test8() {List<Author> authors = getAuthors();Integer sum = authors.stream().distinct().map(author -> author.getAge())//初始值为0,后面 result+=element,最后 return result.reduce(0, (result, element) -> result + element);System.out.println(sum);
}

案例2:使用reduce求所有作者中年龄的最大值

public static void test8() {List<Author> authors = getAuthors();Integer max = authors.stream().map(author -> author.getAge()).reduce(Integer.MIN_VALUE, (result, element) -> result > element ? result : element);System.out.println(max);
}

reduce有个重载形式,内部代码如下:

boolean foundAny = false;
T result = null;
for (T element : this stream) {if(!foundAny) {foundAny = true;result = element;} else {result = accumulator.apply(result, element);}
}
return foundAny ? Optional.of(result) : Optional.empty();

利用这个重载形式,求作者年龄的最大值,不用传递初始值了。

public static void test8() {List<Author> authors = getAuthors();Optional<Integer> max = authors.stream().map(author -> author.getAge()).reduce((result, element) -> result > element ? result : element);System.out.println(max.get());
}

注意事项
惰性求值:如果没有终结操作,中间操作是不会得到执行的。

流是一次性的:一旦一个流对象经过一个终结操作后,这个流就不能再被使用了,只能重新创建流对象再使用。

不会影响原数据:我们在流中可以对数据做很多处理,但正常情况下是不会影响原来集合中的元素的。

相关文章:

  • openJudge | 过滤多余的空格 C语言
  • Leetcode29:两数相除
  • 【python之美】减少人工成本之批量拿取文件名保存_4
  • Rust的Match语句:强大的控制流运算符
  • Gin 中使用 base64Captcha 生成图形验证码
  • flask+python高校学生综合测评管理系统 phl8b
  • 1.JavaScript中的数据类型
  • 小白学习Halcon100例:如何利用动态阈值分割图像进行PCB印刷缺陷检测?
  • DolphinScheduler安装与配置
  • 《零基础实践深度学习》波士顿房价预测任务1.3.3.4训练过程
  • 寒假学习记录13:JS对象
  • 探索XGBoost:自动化机器学习(AutoML)
  • 投资银行在网络安全生态中的作用
  • Python 线性回归可视化 并将回归函数放置到图像上
  • Prompt Tuning:深度解读一种新的微调范式
  • [译]前端离线指南(上)
  • 【许晓笛】 EOS 智能合约案例解析(3)
  • CentOS7简单部署NFS
  • CentOS从零开始部署Nodejs项目
  • cookie和session
  • HTTP请求重发
  • Java的Interrupt与线程中断
  • java多线程
  • Java反射-动态类加载和重新加载
  • Java知识点总结(JDBC-连接步骤及CRUD)
  • leetcode讲解--894. All Possible Full Binary Trees
  • SpiderData 2019年2月25日 DApp数据排行榜
  • Vue2.0 实现互斥
  • 技术发展面试
  • 买一台 iPhone X,还是创建一家未来的独角兽?
  • 如何进阶一名有竞争力的程序员?
  • 新版博客前端前瞻
  • # Swust 12th acm 邀请赛# [ K ] 三角形判定 [题解]
  • #我与Java虚拟机的故事#连载11: JVM学习之路
  • (Mirage系列之二)VMware Horizon Mirage的经典用户用例及真实案例分析
  • (附源码)spring boot基于Java的电影院售票与管理系统毕业设计 011449
  • (附源码)springboot金融新闻信息服务系统 毕业设计651450
  • (四)汇编语言——简单程序
  • (源码版)2024美国大学生数学建模E题财产保险的可持续模型详解思路+具体代码季节性时序预测SARIMA天气预测建模
  • .htaccess 强制https 单独排除某个目录
  • .Net Attribute详解(上)-Attribute本质以及一个简单示例
  • .NET I/O 学习笔记:对文件和目录进行解压缩操作
  • .net 程序 换成 java,NET程序员如何转行为J2EE之java基础上(9)
  • .NET 使用 JustAssembly 比较两个不同版本程序集的 API 变化
  • /ThinkPHP/Library/Think/Storage/Driver/File.class.php  LINE: 48
  • @zabbix数据库历史与趋势数据占用优化(mysql存储查询)
  • [ 云计算 | AWS 实践 ] 基于 Amazon S3 协议搭建个人云存储服务
  • [C++随笔录] 红黑树
  • [CISCN2021 Quals]upload(PNG-IDAT块嵌入马)
  • [CSS] - 修正IE6不支持position:fixed的bug
  • [C语言]——柔性数组
  • [DNS网络] 网页无法打开、显示不全、加载卡顿缓慢 | 解决方案
  • [EMWIN]FRAMEWIN 与 WINDOW 的使用注意
  • [ES-5.6.12] x-pack ssl
  • [flume$2]记录一个写自定义Flume拦截器遇到的错误