用Collectors对List去重
在学习本篇之前,最好对java8新特性有一定的了解。可以参考:Java8新特性--流(Stream)
场景:有一个实体的List集合,需要根据实体中的某个字段对List去重
要想去重,可以考虑使用TreeSet。先来看看TreeSet的用法:
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class Dish { private String id; private String name; }
private static List<Dish> dishList = new ArrayList<Dish>();
static {
Dish dish1 = new Dish("", "张三");
dishList.add(dish1);
Dish dish2 = new Dish("", "李四");
dishList.add(dish2);
Dish dish3 = new Dish("", "王五");
dishList.add(dish3);
}
/**
* 测试TreeSet默认比较器及传入比较器
*/
@Test
public void testTreeSet() {
// TreeSet不传比较器,则默认按照自然顺序排序
TreeSet<Integer> treeSet = new TreeSet<>();
treeSet.add();
treeSet.add();
treeSet.add();
System.out.println(treeSet);
// [1, 3, 4] // TreeSet中的元素,如果是实体,必须得传比较器(或者实体类需要实现Comparable中的compareTo方法),不然就会报错
// TreeSet是Set的子类,里面的元素有序且不能重复,可以去重
TreeSet<Dish> treeSet2 = new TreeSet<>(Comparator.comparing(Dish::getId));
treeSet2.addAll(dishList);
treeSet2.forEach(d -> System.out.println("id:" + d.getId() + ", name:" + d.getName()));
// id:001, name:张三
// id:002, name:王五
}
从上面可以看到TreeSet可以根据实体中的某个字段(这里是id)排序后去重。如果再将TreeSet转为List就可以达到我们的目的:
List<Dish> newDishList = new ArrayList<>(treeSet2);
newDishList.forEach(d -> System.out.println("id:" + d.getId() + ", name:" + d.getName()));
// id:001, name:张三
// id:002, name:王五
虽然大功告成,但是写这么一堆代码,好麻烦。可以使用java8中的收集器简化一下:
/**
* 测试Collectors.toCollection方法:将结果收集到其它类型的集合中(这里是TreeSet)
*/
@Test
public void testToCollection() {
TreeSet<Dish> treeSet2 = dishList.stream()
.collect(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Dish::getId))));
List<Dish> newDishList = new ArrayList<>(treeSet2);
newDishList.forEach(d -> System.out.println("id:" + d.getId() + ", name:" + d.getName()));
// id:001, name:张三
// id:002, name:王五
}
还可以再简单一点:
/**
* 测试Collectors.collectingAndThen方法:将流中的数据通过Collector计算,计算的结果再通过Function处理一下
* (这里是将TreeSet转为ArrayList。即相当于将最终结果又经过了new ArrayList<>(treeSet))
*/
@SuppressWarnings("unchecked")
@Test
public void testCollectingAndThen() {
List<Dish> newDishList = dishList.stream().collect(Collectors.collectingAndThen(
Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Dish::getId))), ArrayList::new));
newDishList.forEach(d -> System.out.println("id:" + d.getId() + ", name:" + d.getName()));
// id:001, name:张三
// id:002, name:王五
}
用Collectors对List去重的更多相关文章
- Java 8 新特性 用 Collectors 对 List 去重
场景:有一个实体的List集合,需要根据实体中的某个字段对List去重 Collectors.collectingAndThen方法:将流中的数据通过Collector计算,计算的结果再通过Funct ...
- list去重jdk1.8
List<Object> newList = ll.stream().distinct().collect(Collectors.toList()); //jdk8去重操作
- java8--List转为Map、分组、过滤、求和等操作----代码示例
Java 8 函数式编程风格 Java 迄今为止最令人激动的特征.这些新的语言特征允许采用函数式风格来进行编码,我们可以用这些特性完成许多有趣的功能.这些特性如此有趣以至于被认为是不合理的.他们说会影 ...
- 关于java8(Stream)的一些用法
如果要处理int[] 转换成 List<Integer>这种形式的,可以用下面这个方法: List<Integer> orgIds = Arrays.stream(reqVo. ...
- Java8新特性(二)——强大的Stream API
一.强大的Stream API 除了Lambda表达式外,Java8另外一项重大更新便是位于java.util.stream.*下的Stream API Stream 是 Java8 中处理集合的关键 ...
- JDK1.8--体验Stream表达式,从一个对象集合中获取每一个对象的某一个值返回新集合
xl_echo编辑整理,欢迎转载,转载请声明文章来源.更多IT.编程案例.资料请联系QQ:1280023003 百战不败,依不自称常胜,百败不颓,依能奋力前行.——这才是真正的堪称强大!! --- 开 ...
- lambda表达式的一些学习
关于lambda表达式的一些学习,例举出来. 1.学生实体类 public class Student { private String name; private int age; public S ...
- Java8 stream用法-备忘录
1. 如何使用匹配模式 List<String> strs = Arrays.asList("a", "a", "a", &qu ...
- JDK新特性——Stream代码简洁之道的详细用法
一.概述 Stream 是一组用来处理数组.集合的API,Stream API 提供了一种高效且易于使用的处理数据的方式. Java 8 中之所以费这么大的功夫引入 函数式编程 ,原因有两个: 代码简 ...
随机推荐
- 程序bug导致了天大的损失,要枪毙程序猿吗?[ZZ]
来自猫扑:程序bug导致了天大的损失,要枪毙程序猿吗? 0 引言 年会上Review 源代码算什么? 法庭上 Review code 才带劲..... 2015年9月3日,随着东京最高法院驳回瑞穗证券 ...
- INDEX--从数据存放的角度看索引
测试表结构: CREATE TABLE TB1 ( ID ,), C1 INT, C2 INT ) 1. 聚集索引(Clustered index) 聚集索引可以理解为一个包含表中除索引键外多有剩余列 ...
- Winform解决界面重绘闪烁的问题
在窗体或用户控件中重写CreateParams protected override CreateParams CreateParams { get { CreateParams cp = base. ...
- MS SQL的某一数据库成了Single User模式
数据库恢复失败,原来的数据却变成了 当尝试打开数据库的属性,即出现上面图片异常的信息. 正常来说,是可以打开数据库的属性 此刻,你可以运行SQL语句来解决: USE master; GO ALTER ...
- AngularJs从数据库获取数据并显示
哈哈,昨天下午和今天早上,花上一些时间,学习AngularJs,仅是粗略预览一下.很好,非常好. 由于手上有开发ASP.NET MVC环境,就在这测试下,去数据库获取数据并显示数据. 数据库表创建,添 ...
- 浏览器环境下JavaScript脚本加载与执行探析之动态脚本与Ajax脚本注入
在<浏览器环境下JavaScript脚本加载与执行探析之defer与async特性>中,我们研究了延迟脚本(defer)和异步脚本(async)的执行时机.浏览器支持情况.浏览器bug以及 ...
- 【CF995F】 Cowmpany Cowmpensation
CF995F Cowmpany Cowmpensation Solution 这道题目可以看出我的代码能力是有多渣(代码能力严重退化) 我们先考虑dp,很容易写出方程: 设\(f_{i,j}\)表示以 ...
- Python2.7更新pip:UnicodeDecodeError: 'ascii' codec can't decode byte 0xb7 in position 7: ordinal not in range(128)
1.首先更新pip版本的时候出现.这是出现在python2.7.16出现的问题 2.进入你的pyhton目录下的Lib\mimetypes.py 打开它 3.在import下面加入这代码 if sys ...
- 网络基础、ftp任务(进度条、计算文件大小、断点续传、搭建框架示例)
一.网络基础 1.端口,是什么?为什么要有端口? 端口是为了将同一个电脑上的不同程序进行隔离. IP是找电脑:端口是找电脑上的应用程序: 端口范围:1 – 65535 : 1 - 1024 不要 ...
- 机器学习与Tensorflow(3)—— 机器学习及MNIST数据集分类优化
一.二次代价函数 1. 形式: 其中,C为代价函数,X表示样本,Y表示实际值,a表示输出值,n为样本总数 2. 利用梯度下降法调整权值参数大小,推导过程如下图所示: 根据结果可得,权重w和偏置b的梯度 ...