java/springboot 如何对装有实体类的list进行去重?
public class User{ private String username;
private String sex;
private Integer age;
}
假设现在有个List<User> list要去重,据我所知主要有两种方法可以去重。
1、遍历这个list,然后利用set.add()来去重(还有几个类似的方法,操作大抵相同)。
2、利用流来处理,list.stream(),然后调用相关的去重方法。
我目前采用的是第一点,但是这里有个细节,就是set.add()里面似乎用了equals()去作比较,故需要重写实体类的equals()和hashCode()两个方法。但是由于equals()可能在其他地方被用到,这么做不确定会不会有影响。
至于第二点,我用main方法自己造数据做测试的时候是没问题的。但在项目中用这个来做去重的话,就会有问题,类似下面的情况:
// 去重前的list有
User("Ben", "男", 12);
User("Ben", "男", 14);
User("Susan", "女", 14);
User("Susan", "女", 13);
// 去重后的list有
User("Ben", "男", 12);
User("Susan", "女", 14);
感觉像是实际去重时,仅凭第一个username变量就完成去重,没有判断其他变量是否相同
1、请问关于带有实体类的list去重,有没有什么好的实现方式?
2、关于我提到的stream()进行过滤的操作所遇到的问题,有没有大神知道是为什么?
请指教,谢谢!
回答:
没用过list.stream()。
单说你第一种方法,利用set来去重是没有任何问题的。
需要重写实体类的equals()和hashCode()两个方法也是必须的。
至于你说的,但是由于equals()可能在其他地方被用到,这么做不确定会不会有影响。
那得看你合并时判断对象相等的规则和“其他地方”判断对象相等的规则是否不一样,我想象不出来这样的场景。
如果“其他地方”需要别的规则,重新定义个equalsNew方法就行了。
回答:
List<User> collect = users.stream().distinct().collect(Collectors.toList());
使用stream()的方式去重也需要重写User类的equals和hashCode方法,根据你的描述,应该是你项目中User类的equals和hashCode方法没写好。
回答:
1:仅仅靠username去重了的话,很明显就是对象的equals和hashCode的规范行为导致(名称相同就是同一个对象),这个你要自己重写(名称+性别+年龄)。
2:stream里面自定义过滤去重规则。
list.stream().filter(LambdaSn.distinctByKey(o -> (o.getUserName() + "_" + o.getSex() + "_" + o.getAge()))).collect(Collectors.toList())
public class LambdaSn {
/** * 根据一个对象的某个字段属性去重,比如 name sex or age,可以用 consumerFunction,自定义构造 去重的key值,比如 name+"_"+sex+"_"+age
*
* @param keyExtractor
* @param <T>
* @return
*/
public static <T> Predicate<T> distinctByKey(Function<? super T, Object> keyExtractor) {
Map<Object, Boolean> seen = new ConcurrentHashMap<>();
return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
}
}
以上是 java/springboot 如何对装有实体类的list进行去重? 的全部内容, 来源链接: utcz.com/p/944226.html