程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 探討:Java中刪除數組中重復元素

探討:Java中刪除數組中重復元素

編輯:關於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. public People(int id,String name){
  5. this.id = id;
  6. this.name = name;
  7. }
  8. @Override
  9. public String toString() {
  10. return ("id = "+id+" , name "+name);
  11. }
  12. }

上面的代碼,用了一個自定義的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. public People(int id,String name){
  5. this.id = id;
  6. this.name = name;
  7. }
  8. @Override
  9. public String toString() {
  10. return ("id = "+id+" , name "+name);
  11. }
  12. public int getId() {
  13. return id;
  14. }
  15. public void setId(int id) {
  16. this.id = id;
  17. }
  18. public String getName() {
  19. return name;
  20. }
  21. public void setName(String name) {
  22. this.name = name;
  23. }
  24. @Override
  25. public boolean equals(Object obj) {
  26. if(!(obj instanceof People))
  27. return false;
  28. People o = (People)obj;
  29. if(id == o.getId()&&name.equals(o.getName()))
  30. return true;
  31. else
  32. return false;
  33. }
  34. @Override
  35. public int hashCode() {
  36. // TODO Auto-generated method stub
  37. return id;
  38. //return super.hashCode();
  39. }
  40. }

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

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved