關鍵字: 如果沒有Set集合,List集合是怎么去除重復元素的(字符串類型)?
*
* 思考: List就可以存儲重復元素,那么需求中容器中的元素必須保證唯一性,該如何解決呢??
*
* 去除List集合中的重復元素?

* * 思路: * * 1.首先我需要另一個臨時容器tempList,用來存放我認為應該保留的元素.(也就是不重復的元素) * 2.然后我們應該遍歷原容器, 一個一個的取出元素, 放入tempList. * 當tempList里已經裝有剛剛取出的元素時,就不要往里放了, * 再繼續取下一個元素對比, * 3.最后都裝完了,我們可以把tempList返回給調用者. * 或者如果調用者希望的結果時還用原來的容器,那么我們 * 也可以清空原來的容器,把tempList的東西都放入到原來容器中. * * 具體步驟: * 1.首先定義一個List集合,至於集合的實現類ArrayList不是我們本題關心的,可以換成其他的實現類也無所謂 * ,因為我們的案例,是關心List集合的特點. * List arrayList = new ArrayList(); * list.add(....); * list.add(....); * * 2.定義一個方法 * delRepeatElements(list) * 小技巧: 寫完方法,在返回結果時,發現當初忘了把這個方法封裝起來,好的,有解決辦法 1.全部選中要封裝的內容 2.ALT+SHIFT+M / 鼠標右鍵Refactor ---> extrac Method 方法中: * 1.定義個一個tempList用來存放臨時元素 * List tempList = new ArrayList(); * * 2.Iterator 遍歷 arrayList 中的元素(注意下面有for的寫法,以及同while的區別) * 取出后用Obeject obj接收. * 進行if判斷,若果不包含 !contans(obj); * 不包含就加入tempList. * 3.根據需求,返回tempList作為結果, * 或者不返回結果,清空原集,將tempList中的元素復制回原集合. * (這里使用了不返回結果,注釋掉了返回結果的部分) * *結論: *1.學習框架體系時,參閱頂層,使用底層.因為這題是要針對List集合的特點,進行推倒,找出弊端. *因為List集合可存放重復元素,那用戶需求偏偏是不需要有重復元素,用List集合怎么解決,所以 *無需關注new 出來的對象是什么類型,只要是能創建實例的實現類都可以,LinkedList還是ArrayList. *2.List在存入元素時,是以Object的形式存入的,並不是String類型,這中間編譯器有一個向上造型的過程. *同樣的,當迭代器從集合中取元素時,取出來的自然也是Object類型了. *那么這樣做就有幾個問題: *1.我想使用我存入對象String類型特有的功能時,就需要強轉.需要Object向下轉型這個過程.麻煩! *這個問題有沒有辦法解決呢? 后續我學到了泛型,解決了此問題.關於泛型知識點,詳見泛型習題. *2.我往集合中存入一個不是String類型的對象,比如Integer,或者我自定義的對象,比如Dog,Person... *集合也收了我的對象,並且編譯運行也沒出錯.我覺得這會給程序帶來不穩定的因素,就算每出錯,同一個集合中 *出現不同的類型的對象,也會在運行時出現不可預知的異常等.這個問題同樣泛型中解決,詳見泛型習題. *3.重復元素去除了,但是僅僅是這種小需求,需要這么多步驟,復雜,麻煩.... *這個問題就是為什么有Set集合出現的必要了. * */ public class ListToRepeat { public static void main(String[] args) { //1.首先定義一個List集合,至於集合的實現類選擇ArrayList,因為我們的案例要求是將List集合中重復的元素刪除, //而ArrayList是可以方重復元素的, 將集合中填入重復元素若干個. List arraylist = new ArrayList(); arraylist.add("abc"); //注意點: 此時存入的"abd"並非String類型,而是Object類型 arraylist.add("abc"); //Object obj = "abc"; 這是一個向上造型的過程 arraylist.add("abcc"); arraylist.add("abcc"); arraylist.add("sdcc"); arraylist.add("abcc"); // arraylist.add(new Dog()); //總結3中的問題. /* 寫完方法,在返回結果時,發現當初忘了把這個方法封裝起來,好的,有解決辦法 * 1.全部選中要封裝的內容 * 2.ALT+SHIFT+M / 鼠標右鍵Refactor ---> extrac Method * */ /*arraylist = */delRepeatElements(arraylist); for(Iterator it = arraylist.iterator(); it.hasNext();){ System.out.println(it.next()); } } public static void delRepeatElements(List list) { //1.定義個一個tempList用來存放臨時元素 List tempList = new ArrayList(); //2.遍歷原容器 迭代器的用法及注意事項 /* 然后我們應該一個一個的取出元素,放入tempList.當tempList里已經裝有剛剛取出的元素時,就不要往里放了, 再繼續取下一個元素對比,這個過程,我想到了迭代器來做. */ for(Iterator it = list.iterator() ; it.hasNext();){ /* 這是一種書寫方式,java建議用這種方式迭代,而不是while. * 兩者的區別: for循環完畢后,Iterator對象就被堆內存釋放了. * while循環結束后,Iterator對象還繼續存在於內存當中. * */ /*取出每一個元素(因為存入時以Object類型存入,取出時自然還是Object類型,需要向下轉型) *本案不用 String str = (String)it.next();*/ Object obj = it.next(); /*注意: 因為我們並沒有用String對象的特有功能,所以此處 沒有進行上面注釋里的強轉步驟.*/ //判斷tempList中是否包含有取出來的這個元素? 如果不包含,則存入tempList if(!(tempList.contains(obj))){ //如果不包含 tempList.add(obj); //添加到tempList容器。 } } //4,遍歷結束后,tempList容器中存儲的就是唯一性的元素。可以返回給調用者 //return tempList; /*5.如果調用者需要將這些唯一性的元素保留到原容器中,只要將原容器清空, 將臨時容器中的元素添加到原容器中即可。*/ //清空原來容器 list.clear(); //把臨時容器中的元素添加到原容器中。 list.addAll(tempList); } }
如果沒有Set集合,List集合是怎么去除重復元素的(自定義類型)

/** 關鍵字: 如果沒有Set集合,List集合是怎么去除重復元素的(自定義類型)? * * 關於去除重復元素的題目的加深思考: (需求變成要求去除相同的自定義類型元素) * 同去除字符串類型相同的是,我們都要進行遍歷,判斷是否包含相同元素. * 這里需要注意的是,相同的自定義類型元素基於對象.equals方法定義的規則之上的,也就是說, * 如果我們我沒有定義自定義類型對象的equals方法,那么這里的包含,就沒有意義,因為只要是new 新對象, * 地址就會不同,也就是說: 本案例中語句 ----tempList.contain(obj)的結果會始終為false; * * 思路: * 1.String類可contains判斷的依據是String重寫了equals方法的,那么同理,我們也要重寫自定義類 * equals方法即可解決問題. */ public class ListToRepeat2 { public static void main(String[] args) { //1.首先定義一個List集合,存儲自定義類型,這里我們新建Dog類描述狗的類 List doglist = new ArrayList(); doglist.add(new Dog("大寶","杜賓",5)); doglist.add(new Dog("小黃","金毛犬",7)); doglist.add(new Dog("鐵球","阿拉斯加",2)); doglist.add(new Dog("大寶","薩摩耶",1)); doglist.add(new Person("小孩",5)); //結論2的問題. doglist.add(new Dog("大寶","薩摩耶",1)); //重復需要去除 doglist.add(new Dog("小黃","金毛犬",7)); //重復需要去除 //刪除重復元素的方法 delRepeatElements(doglist); //遍歷,輸出doglist for(Iterator it = doglist.iterator(); it.hasNext();){ System.out.println(it.next()); } /* 輸出結果: 狗 [名字:大寶, 犬種=杜賓, 年齡=5] 狗 [名字:小黃, 犬種=金毛犬, 年齡=7] 狗 [名字:鐵球, 犬種=阿拉斯加, 年齡=2] 狗 [名字:大寶, 犬種=薩摩耶, 年齡=1] 人類 [name=小孩, age=5] */ /*結論: *1.學習框架體系時,參閱頂層,使用底層.因為這題是要針對List集合的特點,進行推倒,找出弊端. *因為List集合可存放重復元素,那用戶需求偏偏是不需要有重復元素,用List集合怎么解決,所以 *無需關注new 出來的對象是什么類型,只要是能創建實例的實現類都可以,LinkedList還是ArrayList. *2.List在存入元素時,是以Object的形式存入的,並不是String類型,這中間編譯器有一個向上造型的過程. *同樣的,當迭代器從集合中取元素時,取出來的自然也是Object類型了. *那么這樣做就有幾個問題: *1.我想使用我存入對象String類型特有的功能時,就需要強轉.需要Object向下轉型這個過程.麻煩! *這個問題有沒有辦法解決呢? 后續我學到了泛型,解決了此問題.關於泛型知識點,詳見泛型習題. *2.我往集合中存入一個不是String類型的對象,比如Integer,或者我自定義的對象,比如Dog,Person... *集合也收了我的對象,並且編譯運行也沒出錯.我覺得這會給程序帶來不穩定的因素,就算每出錯,同一個集合中 *出現不同的類型的對象,也會在運行時出現不可預知的異常等.這個問題同樣泛型中解決,詳見泛型習題. *3.重復元素去除了,但是僅僅是這種小需求,需要這么多步驟,復雜,麻煩.... *這個問題就是為什么有Set集合出現的必要了.*/ } public static void delRepeatElements(List list) { //1.定義個一個tempList用來存放臨時元素 List tempList = new ArrayList(); //2.遍歷原容器 for(Iterator it = list.iterator() ; it.hasNext();){ Object obj = it.next(); //判斷tempList中是否包含有取出來的這個元素? 如果不包含,則存入tempList //這里需要重寫Dog類的equals方法 if(!(tempList.contains(obj))){ //如果不包含 tempList.add(obj); //添加到tempList容器。 } } //4,遍歷結束后,tempList容器中存儲的就是唯一性的元素。可以返回給調用者 //return tempList; /*5.如果調用者需要將這些唯一性的元素保留到原容器中,只要將原容器清空, 將臨時容器中的元素添加到原容器中即可。*/ //清空原來容器 list.clear(); //把臨時容器中的元素添加到原容器中。 list.addAll(tempList); } } 描述狗的類 /** * 描述狗的類 */ public class Dog { private String name; private String type; private int age; public Dog(String name, String type, int age) { super(); this.name = name; this.type = type; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getType() { return type; } public void setType(String type) { this.type = type; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "狗 [名字:" + name + ", 犬種=" + type + ", 年齡=" + age + "]"; } /* * 重寫equals方法 */ @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Dog other = (Dog) obj; if (age != other.age) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; if (type == null) { if (other.type != null) return false; } else if (!type.equals(other.type)) return false; return true; } } 描述人的類 public class Person { private String name; private int age; @Override public String toString() { return "人類 [name=" + name + ", age=" + age + "]"; } public Person(String name, int age) { super(); this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + age; result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Person other = (Person) obj; if (age != other.age) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; } }