JAVA list 去重

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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章