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,正是實現這個比較。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章