在實際開發的時候,我們經常會碰到這麼乙個問題:乙個集合容器裡面有很多重複的物件,裡面的物件沒有主鍵,或者說忽略主鍵,根據業務的需求,我們需要根據條件篩選出沒有重複的物件。
通過兩層迴圈來進行判斷,沒有重複的元素就加入到新集合中,新集合中已經有的元素就跳過。
實體類使用lombok註解,推薦閱讀:lombok使用指南
實體:
@data@noargsconstructor
@allargsconstructor
public
class
animal
測試:
publicstatic
void
main(string args)
else
}if(!issame)}}
//輸出結果
for(animal animal : newanimallist)
}
輸出結果:
animal(category=犬科, species=狗)animal(category=犬科, species=狼)
animal(category=貓科, species=貓)
animal(category=貓科, species=豹)
一般處理陣列型別的物件時,可以通過這種方法來對陣列元素進行去重操作,以篩選出沒有包含重複元素的陣列。
在使用contains()之前,必須要對animal類重寫equals()方法,如果animal物件不重寫equals(),contains()方法的都是false!新資料與源資料是一樣的,並不能達到我們想要除去重複元素的目的。
那麼contains()是怎麼做到,判斷乙個集合裡面有相同的元素呢?
我們開啟arraylist中contains()方法,原始碼如下:
publicboolean
contains(object o)
找到indexof(o)方法,原始碼如下:
publicintindexof(object o)
else
return -1;
}
如果傳入的物件是null,for迴圈判斷陣列中的元素是否有null,如果有就返回下標;如果傳入的物件不是null,通過物件的equals()方法,for迴圈判斷是否有相同的元素,如果有就返回下標!
如果是陣列返回的下標,肯定是大於0,否則返回-1!
這就是為什麼在list中使用contains()方法,物件需要重寫equals()方法的原因!
重寫equals():
@overridepublic boolean equals(object o)
if (o == null || getclass() != o.getclass())
animal animal = (animal) o;
// 當category、species 內容都相等的時候,才返回true
return objects.equals(category, animal.category) && objects.equals(species, animal.species);
}
測試:
publicstatic
void
main(string args)
}//輸出結果
for(animal animal : newanimallist)
}
輸出結果:
animal(category=犬科, species=狗)animal(category=犬科, species=狼)
animal(category=貓科, species=貓)
animal(category=貓科, species=豹)
使用jdk1.8 中的流式寫法,利用 jdk1.8 中提供的stream.distinct()列表去重,stream.distinct()使用hashcode()和equals()方法來獲取不同的元素,因此使用這種寫法,物件需要重寫hashcode()和equals()方法!
重寫hashcode()方法:
@overridepublic int hashcode()
測試:
publicstatic
void
main(string args)
}
輸出結果:
animal(category=犬科, species=狗)animal(category=犬科, species=狼)
animal(category=貓科, species=貓)
animal(category=貓科, species=豹)
hashset集合天然支援元素不重複!需要同時重寫object中的equals()和hashcode()方法
@data@noargsconstructor
@allargsconstructor
public
class
animal
if (o == null || getclass() !=o.getclass())
animal animal =(animal) o;
//當category、species 內容都相等的時候,才返回true
return objects.equals(category, animal.category) &&objects.equals(species, animal.species);
}@override
public
inthashcode()
}
測試:
publicstatic
void
main(string args)
}
輸出結果:
animal(category=犬科, species=狗)animal(category=犬科, species=狼)
animal(category=貓科, species=貓)
animal(category=貓科, species=豹)
開啟hashset的原始碼,檢視我們傳入的構造方法如下:
public hashset(collection<? extends e>c)
首先建立了乙個hashmap物件,然後呼叫addall()方法
publicboolean addall(collection<? extends e>c)
首先遍歷list中的元素,然後呼叫add()方法,這個方法,原始碼如下:
publicboolean
add(e e)
其實,就是向hashmap物件中插入元素,其中present是乙個new object()常量!
privatestatic
final object present = new object();
到這裡就基本很清楚了,向hashset中新增元素,其實等同於
mapmap = new hashmap();map.put(e,
new object);//
e表示要插入的元素
其中插入的元素e,就是hashmap中的key!
我們知道hashmap,是通過equals()和hashcode()來判斷插入的key是否為同乙個key,因此,當我們對animal物件進行重寫equals()和hashcode()時,保證判斷是同乙個key時,就可以達到元素去重的目的!
最後,對已經去重的集合hashset,再通過arraylist中的addall()方法進行包裝,即可得到我們想要的不包含重複元素的資料!
在C 中如何List去除重複元素?
list中有兩個一樣的元素,想把兩個都去除,用remove和removeall都不行,list中是物件,distinct好像也不太好使,還請各位幫忙解答一下。片段如下 class edge private listedges new list 經過計算後edges中有一些edge物件,有些物件是相同...
HashSet去除List重複元素
使用hashset 去重複 例一,list去重複 public class main 排序 hashset h new hashset list list.clear list.addall h system.out.println 排序後 for string string list 列印結果 去...
去除List集合中的重複值
最近專案中需要對list集合中的重複值進行處理,大部分是採用兩種方法,一種是用遍歷list集合判斷後賦給另乙個list集合,一種是用賦給set集合再返回給list集合。但是賦給set集合後,由於set集合是無序的,原先的順序就打亂了。所以我又想著能不能用set的特性進行去重又不打亂順序呢?試了一下,...