List集合去除重复的对象(不重写equlas和hashcode)

一.前言

    在项目中经常会碰到按某些属性是否相同去去除List集合中的重复对象的问题,每次看网上写的都是什么 “重写自定义对象的equlas和hashCode”千篇一律全是这样,但是真实项目中自定义的对象可能在多个地方用到,每个地方的去重方式都可能不一样,重写肯定是不行的,今天就总结一下不重写对象的equlas和hashCode,去除List中的重复对象。

二. 实现方式

  假设我们有个对象User, 包含四个属性: name、nickName、age、dept,需要根据name和age这两个属性去重,如果这两个属性相同就代表同一个对象

public class User {
	// 姓名
	private String name;
	// 昵称
	private String nickName;
	// 年龄
	private Integer age;
	// 部门
	private String dept;
    
    // 此处省略set和get方法
}

  在list集合中添加5个User对象,分别如下:

public static void main(String[] args) {
		List<User> userList = new ArrayList<>();
		userList.add(new User("张三", "三儿", 20, "销售部"));
		userList.add(new User("李四", "四儿", 23, "销售部"));
		userList.add(new User("张三", "三儿", 20, "销售部"));
		userList.add(new User("张三", "三儿", 20, "研发部"));
		userList.add(new User("王五", "五儿", 21, "研发部"));
}

   现在我们想要去除userList集合中拥有相同姓名和年龄的User,但是又不想重写User实体类的equlas和hashCode方法,那么该怎么做呢?

   第一种方式:for循环倒叙删除:

   即:使用两层循环,内层循环从后往前删

		// int size = userList.size(); 此处一定不要在这里将size写死,因为size是一直在变的
		for (int i = 0; i < userList.size(); i ++) {
			User outU = userList.get(i);
			for (int j = userList.size() - 1; j > i; j--) { // 内层循环从 size() -1开始
				User inU = userList.get(j);
				if (inU.getName().equals(outU.getName()) && inU.getAge() == outU.getAge()) {
					userList.remove(j);
				}
			}
		}

  结果如下:

已经成功的删除掉了相同姓名和年龄的对象。

 第二种方式:使用Set集合去除重复元素:

		Set<User> set = new TreeSet<>(new Comparator<User>() {
			@Override
			public int compare(User o1, User o2) {
				// 这里按照自己的需求来添加属性即可
				return (o1.getName().compareTo(o2.getName())) + (o1.getAge() - o2.getAge()));
			};
		});
		set.addAll(userList);
		printList(new ArrayList<>(set));

  开始在这里有点疑问,当时不明白为什么加入一个new Comparator比较器重写compart方法就可以去重呢? 一个“比较”的方法还能够去重? 后来看了一个Set的源码搞明白了,其实Set集合的底层是用Map实现的,去重的原理即是用到了比较,首先看hashCode是否相同,如果相同再去比较equals,如果equals也相同就不再存储,而我们的比较器Comparator,正是实现这个比较。

 

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值