qileilove

          blog已經(jīng)轉(zhuǎn)移至github,大家請?jiān)L問 http://qaseven.github.io/

          Java中刪除數(shù)組中重復(fù)元素

          這個(gè)是一個(gè)老問題,但是發(fā)現(xiàn)大多數(shù)人說的還不夠透。小弟就在這里拋磚引玉了,歡迎拍磚.......

            問題:比如我有一個(gè)數(shù)組(元素個(gè)數(shù)為0哈),希望添加進(jìn)去元素不能重復(fù)。

            拿到這樣一個(gè)問題,我可能會快速的寫下代碼,這里數(shù)組用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.     }

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

            問題:加入已經(jīng)有一些元素的數(shù)組了,怎么刪除這個(gè)數(shù)組里重復(fù)的元素呢?

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

          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. }

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

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

           這里的backingMap也就是HashSet維護(hù)的數(shù)據(jù),它用了一個(gè)很巧妙的方法,把每次添加的Object當(dāng)作HashMap里面的KEY,本身HashSet對象當(dāng)作VALUE。這樣就利用了Hashmap里的KEY唯一性,自然而然的HashSet的數(shù)據(jù)不會重復(fù)。但是真正的是否有重復(fù)數(shù)據(jù),就得看HashMap里的怎么判斷兩個(gè)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     }

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

          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. }

            這里在調(diào)用removeDuplicate(list)方法就不會出現(xiàn)兩個(gè)相同的people了。



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


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


          網(wǎng)站導(dǎo)航:
           
          <2012年1月>
          25262728293031
          1234567
          891011121314
          15161718192021
          22232425262728
          2930311234

          導(dǎo)航

          統(tǒng)計(jì)

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 清新县| 玉环县| 乐平市| 娄烦县| 铜鼓县| 长丰县| 怀柔区| 石首市| 邢台市| 根河市| 蓬莱市| 贵定县| 宿州市| 凤山市| 扶余县| 诏安县| 新余市| 诸暨市| 芮城县| 太白县| 墨竹工卡县| 渑池县| 新密市| 富裕县| 香港 | 宁德市| 健康| 澳门| 晋中市| 甘南县| 高陵县| 宜宾县| 南陵县| 遂溪县| 壶关县| 资源县| 尉犁县| 建湖县| 嵊泗县| 成都市| 怀化市|