本文内容都是个人思索,并未找到官方文档,请大佬评论指正:

需求:对根据对象里面的特定字段,完成对象元素去重;

public class Test4 {
static List ans = Lists.newArrayList(new User(“a”),
new User(“a”), new User(“b”), new User(“c”));

/*** 创建的是Predicate对象,而创建代码只会走一次,*/
public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {Set<Object> seen = ConcurrentHashMap.newKeySet();System.out.println("--->创建seen:" + seen);return t -> {System.out.println("filter操作" + t);return seen.add(keyExtractor.apply(t));};
}@Data
@AllArgsConstructor
@NoArgsConstructor
public static class UserEx {private String name;}@Data
@AllArgsConstructor
@NoArgsConstructor
public static class User {private String name;
}

}
普通版
普通写法:在外部定义一个Set集合,然后利于set的add方法完成去重。

public static void main(String[] args) {//流式去重Set<String> seen = new HashSet<>();ans.stream().filter(a -> seen.add(a.getName())).collect(Collectors.toList());
}

但是能不能将去重逻辑抽取为一个通用的静态方法:

进阶版
public static Predicate distinctByKey(Function<? super T, ?> keyExtractor) {
Set seen = ConcurrentHashMap.newKeySet();
return t -> seen.add(keyExtractor.apply(t));
}
使用方式:

public static void main(String[] args) {//流式去重Set<String> seen = new HashSet<>();ans.stream().filter(distinctByKey(User::getName)).collect(Collectors.toList());
}

但是细心的小伙伴可以发现,因为Stream流会多次执行filter操作,是不是会多次调用distinctByKey逻辑,每一次都创建一个Set集合,如何达到去重的效果呢???

打印日志:

public static void main(String[] args) {//lambda表达式传入java.util.function类型List<UserEx> collect = ans.stream().map(r -> {System.out.println("前置map操作" + r);return new UserEx(r.name);}).filter(distinctByKey(UserEx::getName)).peek(r -> System.out.println("后置peek操作" + r)).collect(Collectors.toList());
}/*** 创建的是Predicate对象,而创建代码只会走一次,*/
public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {Set<Object> seen = ConcurrentHashMap.newKeySet();System.out.println("--->创建seen:" + seen);return t -> {System.out.println("filter操作" + t);return seen.add(keyExtractor.apply(t));};
}

执行效果:

—>创建seen:[]
前置map操作Test4.User(name=a)
filter操作Test4.UserEx(name=a)
后置peek操作Test4.UserEx(name=a)
前置map操作Test4.User(name=a)
filter操作Test4.UserEx(name=a)
前置map操作Test4.User(name=b)
filter操作Test4.UserEx(name=b)
后置peek操作Test4.UserEx(name=b)
前置map操作Test4.User(name=c)
filter操作Test4.UserEx(name=c)
后置peek操作Test4.UserEx(name=c)
[Test4.UserEx(name=a), Test4.UserEx(name=b), Test4.UserEx(name=c)]
可以看到:在最开始的时候,Set只创建了一次,在执行filter操作时,并未创建Set。

推测:stream 第一步先构建管道,第二步数据才真正流转。

后续可以利用这个特效来提供一个更加便利的工具方法。

颠覆认知的Java-lambda流特效:构建管道->数据流转相关推荐

  1. java接收流文件并返回数据

    java接收流文件并返回数据 @RequestMapping(value="/updateStatus") public Object updateStatus(HttpServl ...

  2. Java Lambda流和Groovy Clouse的比较

    这篇博客文章将探讨List数据结构上的一些谚语操作,并对Java 8/9和Groovy语法进行一些比较. 因此,首先是数据结构. 这只是一个简单的橄榄球球员,有名字和等级. Java class Ru ...

  3. libnet发包java语言_Libnet11手动构建IPv6数据包

    我正在尝试使用 Libnet11 函数: int libnet_write_raw_ipv6 (libnet_t *l, u_int8_t *packet, u_int32_t size) 在网络层注 ...

  4. java lambda::_基准测试:Java 8 Lambda和流如何使您的代码慢5倍

    java lambda:: 与长期的实现相比,Java 8 lambda和流的性能如何? Lambda表达式和流在Java 8中受到了热烈的欢迎.这些是迄今为止很激动人心的功能,很长一段时间以来,它们 ...

  5. 深入理解Java Lambda表达式,匿名函数,闭包

    前言 对于Lambda表达式一直是知其然不知其所以然,为了搞清楚什么是Lambda表达式,以及Lambda表达式的用法和作用,本文应运而生当做学习笔记分享出来,欢迎指正交流. 什么是Lambda 让我 ...

  6. java8流分组 性能_Java性能教程– Java 8流有多快?

    java8流分组 性能 在此JAX Magazine的预览预览中,JAX伦敦发言人Angelika Langer为使用Java流的任何人回答了最重要的问题:它们真的更快吗? Java 8是JDK收集框 ...

  7. java 8流自定义收集器_Java 8编写自定义收集器简介

    java 8流自定义收集器 Java 8引入了收集器的概念. 大多数时候,我们几乎不使用Collectors类中的工厂方法,例如collect(toList()) , toSet()或其他更有趣的方法 ...

  8. Java性能教程– Java 8流有多快?

    在此JAX Magazine的预览预览中,JAX伦敦发言人Angelika Langer为使用Java流的任何人回答了最重要的问题:它们真的更快吗? Java 8是JDK收集框架的主要新增功能,即流A ...

  9. Java stream流式计算详解

    Java stream流式计算详解 1. Stream概述 1.1 Stream简介 1.2 Stream分类 2. Stream操作 2.1 Stream创建 2.2 Stream无状态操作 2.3 ...

最新文章

  1. 青少年编程竞赛交流群周报(第039周)
  2. velocity 模板语言(VTL)
  3. 恢复SAP IDES中SPFLI SFLIGHT SBOOK表数据
  4. 【Python】面向小白的Python可视化教程,超全的!
  5. 2021-09-211547G - How Many Paths?
  6. Java程序员应该了解的10个设计原则
  7. 把本地的jar包打包到maven本地仓库里
  8. win10更换系统启动时候的图片
  9. windows下git ssh密钥生成
  10. BIGEMAP如何将高程数据(等高线)转换成xi'an80或者beijing54坐标系
  11. 使用iToolab UnlockGo 删除iPhone/iPad上的各种锁
  12. Webgl(ThreeJS)空间测量\测距功能(附工程文件)
  13. 计算机类银行招聘考试考什么科目,计算机专业参加银行招聘考试要考哪些科目,除了行..._银行招聘考试_帮考网...
  14. 模拟电子技术之运算放大器
  15. 2018区块链技术及应用峰会(BTA)倒计时2天,最强百人区块链大咖齐聚
  16. 在线客服系统对接微信小程序(客服消息推送)
  17. 用elasticsearch和nuxtjs搭建bt搜索引擎
  18. 阿里云 实现流媒体 直播 demo
  19. 十分钟掌握多项式回归:拟合非线性关系
  20. 微信小程序 向下跳动箭头

热门文章

  1. 河海大学计算机专业有哪些,南京师范大学和河海大学的计算机专业
  2. android7.0root工具,你与玩转Android 7.0,只差一个KingRoot的距离
  3. 原生支付宝小程序对接诸葛io监测
  4. 关于Linux下文件删除文件时提示No such file or directory的解决办法
  5. 你公司的虚拟机还闲着?基于 Jenkins 和 Kubernetes 的持续集成测试实践了解一下!...
  6. Allegro(17.2)——常用菜单栏(3)
  7. Python可以自学吗?
  8. vue3 ts 使用 pinia
  9. MAC jmeter+ant 实现接口测试并将接口测试报告以邮件的形式发出-超详细
  10. CodeBlocks使用小技巧