List根据属性去重

创建一个user集合

 User user1 = new User("user1", 18, "AAA");
User user2 = new User("user2", 18, "BBB");
User user3 = new User("user3", 18, "AAA");
User user4 = new User("user4", 75, "CCC");
User user5 = new User("user5", 35, "AAA"); ArrayList<User> list = new ArrayList<>();
list.add(user1);
list.add(user2);
list.add(user3);
list.add(user4);
list.add(user5);

自定义Predict函数,使用filter()

写一个Predict
public class DistinctKeyUtil {
public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
ConcurrentHashMap<Object, Boolean> map = new ConcurrentHashMap<>();
return t -> map.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
}
}
使用filter方法
/**
* 写一个Predict进行属性过滤
*/
//先过滤age在过滤hobby
List<User> result = list.stream()
.filter(DistinctKeyUtil.distinctByKey(n -> n.getAge()))
.filter(DistinctKeyUtil.distinctByKey(n -> n.getHobby()))
.collect(Collectors.toList()); result.forEach(System.out::println);
结果:
User{name='user1', age=18, hobby='AAA'}
User{name='user4', age=75, hobby='CCC'}
小结:

实质上是将每个元素都放到distinctByKey()中的ConcurrentHashMap作为key进行过滤,如果key不存在那么就加上去,如果已经存在了就不加。所以这种方式的过滤只保留第一个重复元素。

利用TreeSet

        //过滤age
ArrayList<User> result2 = list.stream().collect(
Collectors.collectingAndThen(
Collectors.toCollection(
() -> new TreeSet<>(Comparator.comparing(o -> o.getAge()))), ArrayList::new)); result2.forEach(System.out::println);

结果与上面的一样

同时过滤两个属性

        //age和hobby一起过滤
ArrayList<User> result1 = list.stream().collect(
Collectors.collectingAndThen(
Collectors.toCollection(
() -> new TreeSet<>(Comparator.comparing(o -> o.getHobby() + ";" + o.getAge()))), ArrayList::new)
);
result1.forEach(System.out::println);
结果:
User{name='user1', age=18, hobby='AAA'}
User{name='user5', age=35, hobby='AAA'}
User{name='user2', age=18, hobby='BBB'}
User{name='user4', age=75, hobby='CCC'}
小结:

TreeSet存储唯一的元素,并且按升序对元素进行排序。

Map:保证Key的唯一性

        /**
* map 根据某属性过滤
*/
// Function.identity() 相等于 o->o
Map<String, User> map1 = list.stream().collect(Collectors.toMap(User::getHobby, Function.identity(), (t1, t2) -> t1));
Set<Map.Entry<String, User>> entries1 = map1.entrySet();
entries1.forEach(System.out::println);
结果:
AAA=User{name='user1', age=18, hobby='AAA'}
CCC=User{name='user4', age=75, hobby='CCC'}
BBB=User{name='user2', age=18, hobby='BBB'}
小结:

map可以选择保留重复属性中的前一条数据还是后一条:(t1, t2) -> t1)

Stream流根据属性去重的更多相关文章

  1. JDK 8 中Stream流中的去重的方法

    JDK 8 中Stream流中去重的方法 1.简单的去重,可以使用distinct()方法去重,该方法是通过比较equals和hashcode值去去重, 2.复杂的去重, 例如,在一个JavaBean ...

  2. 【JDK8】JDK 8 中Stream流中的去重的方法

    JDK 8 中Stream流中去重的方法 1.简单的去重,可以使用distinct()方法去重,该方法是通过比较equals和hashcode值去去重, 2.复杂的去重, 例如,在一个JavaBean ...

  3. Stream流用于按照对象中某一属性来对集合去重+简单数据类型集合的去重

    上次对Stream流来进行分组的文章很多人看,想看的可以来这: Stream流来进行集合分组 这次小编又带来Stream的去重,话不多数,直接上代码: 这是对简单数据类型的去重 //字符串集合进行简单 ...

  4. List使用Stream流进行集合Collection的各种运算汇总:对BigDecimal求和,某个字段的和、最大值、最小值、平均值,字段去重,过滤等

    写Java接口的朋友都知道,Java 8的更新,经常会用到过滤 list<Object> 里的数据,本文就对List使用Stream流进行集合Collection的各种运算做一个汇总! 优 ...

  5. (六)jdk8学习心得之Stream流

    六.Stream流 1. 什么是stream流 现阶段,可以把stream流看成一个高级版的Iterator.普通的Iterator只能实现遍历,遍历做什么,就需要具体些功能代码函数了.而这个stre ...

  6. 简洁方便的集合处理——Java 8 stream流

    背景 java 8已经发行好几年了,前段时间java 12也已经问世,但平时的工作中,很多项目的环境还停留在java1.7中.而且java8的很多新特性都是革命性的,比如各种集合的优化.lambda表 ...

  7. Java的Stream流式操作

    前言 最近在实习,在公司看到前辈的一些代码,发现有很多值得我学习的地方,其中有一部分就是对集合使用Stream流式操作,觉得很优美且方便.所以学习一下Stream流,在这里记录一下. Stream是什 ...

  8. 再来看看Java的新特性——Stream流

    半年前开始试着使用Java的新特性,给我印象最深的就是Stream流和Optional.其中Stream提高了看法效率,让代码看起来十分清爽. 为什么要使用流? 摘要中已经说明了,为了提高开发效率.流 ...

  9. 详解 stream流

    在本人之前的博文中,我们学习了 I/O流.NIO流的相关概念. 那么,在JDK8的更新内容中,提出了一个新的流 -- stream流 那么,现在,本人就来讲解下这个流: 目录 stream流 常用AP ...

  10. List集合对象去重及按属性去重的8种方法-java基础总结系列第六篇

    最近在写一些关于java基础的文章,但是我又不想按照教科书的方式去写知识点的文章,因为意义不大.基础知识太多了,如何将这些知识归纳总结,总结出优缺点或者是使用场景才是对知识的升华.所以我更想把java ...

随机推荐

  1. layui tree 未命名 所遇到的坑

    由于传入类型不对,需要传入object类型,我传入的是String类型,所以出现了 一堆未命名, 在控制台输出查看,是一模一样的,困扰了我一下午,再次感谢老哥 参考自:https://www.cnbl ...

  2. ElseViewer--校稿

    1Edit ModeThis presents the proof in continuous scroll to review and make corrections. By default, y ...

  3. JavaWeb学习笔记第三弹

    一.数据库设计 1.软件研发步骤 2.数据库设计概念 建立数据库中的表结构以及表与表之间的关联关系的过程 3.数据库设计的步骤 表关系:一对一.一对多(多对一).多对多 表关系之一对多 表关系之多对多 ...

  4. Django笔记一之运行系统、创建视图并访问

    从这一篇笔记开始将根据 Django 的官方文档,阅读整理之后,出一系列笔记教程,用作新手入门教程或者自己做查阅. 此次 Django 的版本为 3.2,且之后的一系列笔记都将以这个版本为基础,做功能 ...

  5. Linux RedHat 利用 ISO镜像文件制作本地 yum源

    RedHat 利用ISO镜像文件制作本地yum源 [1]创建iso存放目录和挂载目录 1 [root@desktop ~]# cd /mnt/ 2 [root@desktop mnt]# mkdir ...

  6. nodsjs POST请求

    PHP 遇到问题: 1.跨域问题 报failed to load response data:no data fond for response with give header("Cont ...

  7. 什么时候需要使用try-catch

    代码执行预料不到的情况,或出错的可能性很大时,使用try-catch语句 构造一个文件输入流(上传文件时,线上环境的内存情况不确定)出错的可能性很大 文件上传写入, 数据库事务的提交,还有摄像头和打印 ...

  8. 如何在Solidity中建立DAO(去中心化自治组织)?

    本文将帮助您理解 DAO 的概念,并帮助您构建一个基本的 DAO. 什么是 DAO? 您可以将 DAO 视为基于互联网的实体(比如企业),由其股东(拥有代币和比例投票权的成员)共同拥有和管理.在 DA ...

  9. 系统优化脚本支持Ubuntu和CentOS

    系统优化脚本支持Ubuntu和CentOS 经常会部署各种用途的操作系统,但在这些工作中,我们会发现很多工作其实是重复性的劳动,操作的内容也是大同小异,基于这类情况,我们可以把相同的操作做成统一执行的 ...

  10. window设置开启启动程序的几种方式比较

    一.设置开机启动项 进入启动文件夹,拷贝程序的快捷方式到这个文件夹即可. 可在任务管理器--启动,查看是否设置成功 启动时间:用户登陆之后. 二.使用计划任务设置自启 进入计划任务界面进行配置,按wi ...