ArrayList 去重
在寫java代碼中會用到ArrayList,使用過程中有一些比較奇葩的業務,需要對重複的數據去重。
在網上找了幾種方法
- 利用HashSet裏面的元素不可重複
- 利用list裏面contains方法比較是否存在去重
首頁我試驗了第一種方法
public static void main(String args[]){
ArrayList<Integer> arrayList = new ArrayList<>();
arrayList.add(1);
arrayList.add(2);
arrayList.add(1);
arrayList.add(3);
arrayList.add(2);
arrayList.add(3);
arrayList = new ArrayList<>(new HashSet<>(arrayList));
for (int i=0;i<arrayList.size();i++){
printlns("arrayList ["+ i +"] = "+arrayList.get(i));
}
}
運行結果
arrayList [0] = 1
arrayList [1] = 2
arrayList [2] = 3
發現確實能行啊,成功了。但是這裏排重的是 Integer 類型,如果換成String 類型呢
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("1");
arrayList.add("2");
arrayList.add("2");
arrayList.add("3");
arrayList.add("2");
arrayList.add("1");
運行結果
arrayList [0] = 1
arrayList [1] = 2
arrayList [2] = 3
發現也行,這下放心了,後來在項目中遇到問題,如果換成對象能實現嗎
所以我就加入了User對象
static class User{
public User(String name, int age) {
this.name = name;
this.age = age;
}
String name;
int age;
}
並且修改了測試數據
ArrayList<User> arrayList = new ArrayList<>();
arrayList.add(new User("111",10));
arrayList.add(new User("111",10));
arrayList.add(new User("222",20));
arrayList.add(new User("111",10));
arrayList.add(new User("222",20));
arrayList.add(new User("333",30));
arrayList.add(new User("111",10));
arrayList.add(new User("111",10));
arrayList = new ArrayList<>(new HashSet<User>(arrayList));
運行結果
arrayList [0] = 111 , 10
arrayList [1] = 111 , 10
arrayList [2] = 222 , 20
arrayList [3] = 111 , 10
arrayList [4] = 333 , 30
arrayList [5] = 111 , 10
arrayList [6] = 222 , 20
arrayList [7] = 111 , 10
發現去重失敗,然後我又看了一下Hastset去重原理:發現HashSet裏面比較用equals方法,不對,其實應該是equals和hascode方法。
這裏修改一下User類
static class User{
public User(String name, int age) {
this.name = name;
this.age = age;
}
String name;
int age;
@Override
public boolean equals(Object o) {
if(this == o){
return true;
}
if(o == null){
return false;
}
if(getClass() != o.getClass()){
return false;
}
User user = (User) o;
if(age != user.age){
return false;
}
if(name == null){
if(user.name !=null){
return false;
}
}else{
if(!name.equals(user.name)){
return false;
}
}
return true;
}
@Override
public int hashCode() {
return 1;
}
}
運行結果
arrayList [0] = 111 , 10
arrayList [1] = 222 , 20
arrayList [2] = 333 , 30
成功了,幹活
Object 中 hasCode
1. 在一個進程執行期間,如果一個對象的equals的方法做比較所用到的信息沒有被修改的話,則對象調用hashCode方法多次,它必須始終如一的返回同一個整數。
2. 如果兩個對象根據equals(Object o)方法是相等的,則調用者兩個對象中任意一對象的hashCode方法必須產生相同的結果
3. 如果兩個對象根據equals(Object o)方法是不相等的,則調用這個兩個對象中任一個對象的hashCode方法返回值不要產生不同的整數,但是如果不同的話,可以提高散列表的性能。
在HastSet中,基本的操作都是由HashMap低層實現的,因爲HastSet底層是用HashMap來存儲數據。當向HastSet中添加元素時,首先計算元素的Hashcode值,然後用這個(元素的hashcode)%(HashMap集合的大小)+1計算出這個元素的存儲位置,如果這個位置位空,就將元素添加進去;如果不爲空,則用equals方法比較元素是否相等,相等就不添加,否則找一個空位添加。
到這裏第一種方法
第二種方法,那就來了用到contains方法來判斷比較,和第一種方法類似,也是用equals方法來判斷。
public static List removeDuplicateWithOrder(List list) {
List newList = new ArrayList();
for (Object o : list) {
if (!newList .contains(o)) newList.add(o);
}
return newList;
}