qileilove

          blog已經轉移至github,大家請訪問 http://qaseven.github.io/

          Java中刪除數組中重復元素

          這個是一個老問題,但是發現大多數人說的還不夠透。小弟就在這里拋磚引玉了,歡迎拍磚.......

            問題:比如我有一個數組(元素個數為0哈),希望添加進去元素不能重復。

            拿到這樣一個問題,我可能會快速的寫下代碼,這里數組用ArrayList.

          1. private static void testListSet(){  
          2.         List<String> arrays = new ArrayList<String>(){  
          3.             @Override 
          4.             public boolean add(String e) {  
          5.                 for(String str:this){  
          6.                     if(str.equals(e)){  
          7.                         System.out.println("add failed !!!  duplicate element");  
          8.                         return false;  
          9.                     }else{  
          10.                         System.out.println("add successed !!!");  
          11.                     }  
          12.                 }  
          13.                 return super.add(e);  
          14.             }  
          15.         };  
          16.                 arrays.add("a");arrays.add("b");arrays.add("c");arrays.add("b");  
          17.         for(String e:arrays)  
          18.             System.out.print(e);  
          19.     }

            這里我什么都不關,只關心在數組添加元素的時候做下判斷(當然添加數組元素只用add方法),是否已存在相同元素,如果數組中不存在這個元素,就添加到這個數組中,反之亦然。這樣寫可能簡單,但是面臨龐大數組時就顯得笨拙:有100000元素的數組天家一個元素,難道要調用100000次equal嗎?這里是個基礎。

            問題:加入已經有一些元素的數組了,怎么刪除這個數組里重復的元素呢?

            大家知道java中集合總的可以分為兩大類:List與Set。List類的集合里元素要求有序但可以重復,而Set類的集合里元素要求無序但不能重復。那么這里就可以考慮利用Set這個特性把重復元素刪除不就達到目的了,畢竟用系統里已有的算法要優于自己現寫的算法吧。

          1. public static void removeDuplicate(List<People> list){  
          2.    HashSet<People> set = new HashSet<People>(list);  
          3.    list.clear();  
          4.    list.addAll(set);  
          5. }  
          6. ivate static People[] ObjData = new People[]{  
          7.     new People(0"a"),new People(1"b"),new People(0"a"),new People(2"a"),new People(3"c"),  
          8. };

          1. public class People{  
          2.     private int id;  
          3.     private String name;  
          4.       
          5.     public People(int id,String name){  
          6.         this.id = id;  
          7.         this.name = name;  
          8.     }  
          9.       
          10.     @Override 
          11.     public String toString() {  
          12.         return ("id = "+id+" , name "+name);  
          13.     }  
          14.       
          15. }

            上面的代碼,用了一個自定義的People類,當我添加相同的對象時候(指的是含有相同的數據內容),調用removeDuplicate方法發現這樣并不能解決實際問題,仍然存在相同的對象。那么HashSet里是怎么判斷像個對象是否相同的呢?打開HashSet源碼可以發現:每次往里面添加數據的時候,就必須要調用add方法:

          1.       @Override 
          2.      public boolean add(E object) {  
          3.          return backingMap.put(object, this) == null;  
          4.      }

           這里的backingMap也就是HashSet維護的數據,它用了一個很巧妙的方法,把每次添加的Object當作HashMap里面的KEY,本身HashSet對象當作VALUE。這樣就利用了Hashmap里的KEY唯一性,自然而然的HashSet的數據不會重復。但是真正的是否有重復數據,就得看HashMap里的怎么判斷兩個KEY是否相同。

          1.         @Override public V put(K key, V value) {  
          2. 390         if (key == null) {  
          3. 391             return putValueForNullKey(value);  
          4. 392         }  
          5. 393   
          6. 394         int hash = secondaryHash(key.hashCode());  
          7. 395         HashMapEntry<K, V>[] tab = table;  
          8. 396         int index = hash & (tab.length - 1);  
          9. 397         for (HashMapEntry<K, V> e = tab[index]; e != null; e = e.next) {  
          10. 398             if (e.hash == hash && key.equals(e.key)) {  
          11. 399                 preModify(e);  
          12. 400                 V oldValue = e.value;  
          13. 401                 e.value = value;  
          14. 402                 return oldValue;  
          15. 403             }  
          16. 404         }  
          17. 405   
          18. 406         // No entry for (non-null) key is present; create one  
          19. 407         modCount++;  
          20. 408         if (size++ > threshold) {  
          21. 409             tab = doubleCapacity();  
          22. 410             index = hash & (tab.length - 1);  
          23. 411         }  
          24. 412         addNewEntry(key, value, hash, index);  
          25. 413         return null;  
          26. 414     }

            總的來說,這里實現的思路是:遍歷hashmap里的元素,如果元素的hashcode相等(事實上還要對hashcode做一次處理),然后去判斷KEY的eqaul方法。如果這兩個條件滿足,那么就是不同元素。那這里如果數組里的元素類型是自定義的話,要利用Set的機制,那就得自己實現equal與hashmap(這里hashmap算法就不詳細介紹了,我也就理解一點)方法了:

          1. public class People{  
          2.     private int id; //  
          3.     private String name;  
          4.       
          5.     public People(int id,String name){  
          6.         this.id = id;  
          7.         this.name = name;  
          8.     }  
          9.       
          10.     @Override 
          11.     public String toString() {  
          12.         return ("id = "+id+" , name "+name);  
          13.     }  
          14.      
          15.     public int getId() {  
          16.         return id;  
          17.     }  
          18.  
          19.     public void setId(int id) {  
          20.         this.id = id;  
          21.     }  
          22.  
          23.     public String getName() {  
          24.         return name;  
          25.     }  
          26.  
          27.     public void setName(String name) {  
          28.         this.name = name;  
          29.     }  
          30.  
          31.     @Override 
          32.     public boolean equals(Object obj) {  
          33.         if(!(obj instanceof People))  
          34.             return false;  
          35.         People o = (People)obj;  
          36.         if(id == o.getId()&&name.equals(o.getName()))  
          37.             return true;  
          38.         else 
          39.             return false;  
          40.     }  
          41.       
          42.     @Override 
          43.     public int hashCode() {  
          44.         // TODO Auto-generated method stub  
          45.         return id;  
          46.         //return super.hashCode();  
          47.     }  
          48. }

            這里在調用removeDuplicate(list)方法就不會出現兩個相同的people了。



          posted on 2012-01-16 14:14 順其自然EVO 閱讀(725) 評論(0)  編輯  收藏


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          <2012年1月>
          25262728293031
          1234567
          891011121314
          15161718192021
          22232425262728
          2930311234

          導航

          統計

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 滕州市| 昌宁县| 嘉黎县| 上高县| 车致| 华池县| 睢宁县| 理塘县| 报价| 凤城市| 祁门县| 于都县| 延津县| 安阳市| 仙桃市| 辰溪县| 驻马店市| 新源县| 应用必备| 白河县| 兰州市| 襄樊市| 东台市| 汾西县| 商洛市| 永丰县| 中卫市| 芮城县| 六盘水市| 铜陵市| 宝鸡市| 德州市| 呼图壁县| 安远县| 崇州市| 达日县| 虎林市| 诏安县| 炎陵县| 天柱县| 离岛区|