思路:創建一個新ArrayList集合,遍歷舊集合,判斷新集合中是否包含舊集合中的元素,有就跳過,沒有就加進去。
按照上邊思路,分以下兩種情況進行操作:
1)集合中存放的爲String字符串類型
public static void main(String[] args) { ArrayList list=new ArrayList(); list.add("hello"); list.add("hello"); list.add("hello"); list.add("hello"); list.add("world"); list.add("world"); list.add("world"); //通過創建新集合的方式 ArrayList newarray=new ArrayList<>(); for (int i = 0; i < list.size(); i++) { if (!newarray.contains(list.get(i))) { newarray.add(list.get(i)); } } for (int i = 0; i < newarray.size(); i++) { System.out.println(newarray.get(i)); } } |
輸出結果爲:
hello world |
2.集合中存放的爲引用對象的情況
自定義對象:
public class Student { private String name; private int 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; } public Student() { super(); } public Student(String name, int age) { super(); this.name = name; this.age = age; } } |
public static void main(String[] args) { Student s1=new Student("釋小龍", 20); Student s2=new Student("奔跑", 21); Student s3=new Student("釋小龍", 20); Student s4=new Student("奔跑", 21); List<Student>list=new ArrayList<>(); list.add(s1); list.add(s2); list.add(s3); list.add(s4); List<Student> newarray=new ArrayList<>(); for (int i = 0; i < list.size(); i++) { if (!newarray.contains(list.get(i))) { newarray.add(list.get(i)); } } for (int i = 0; i < newarray.size(); i++) { System.out.println(newarray.get(i).getName()+":"+newarray.get(i).getAge()); } } |
輸出結果爲:
釋小龍:20 奔跑:21 釋小龍:20 奔跑:21 |
結果沒有去重,爲什麼呢?
通過查看設計到的算法,遍歷集合,查找集合都沒問題,問題應該出現在contains方法比較中,查看contains的實現源碼如下:
public boolean contains(Object o) { return indexOf(o) >= 0; } public int indexOf(Object o) { if (o == null) { for (int i = 0; i < size; i++) if (elementData[i]==null) return i; } else { for (int i = 0; i < size; i++) if (o.equals(elementData[i])) return i; } return -1; } |
發現源碼中比較是否相同時,用的是o.equals方法,即調用的爲傳進來對象的equals方法,但自定義對象中,沒有定義equals方法,於是調用的應該是父類Object中的equals方法,而父類equals方法中默認比較的爲某個對象的引用地址,每個new出來的對象都有一個新的地址,地址不同,所以判斷時都爲不包含,故輸出結果爲舊對象中所有值。
解決辦法:改進自定義對象,在其中加入equals方法
改進後的自定義對象
public class Student { private String name; private int 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; } public Student() { super(); } public Student(String name, int age) { super(); this.name = name; this.age = age; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Student other = (Student) 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; } } |
再次輸出結果:
釋小龍:20 奔跑:21 |
去重成功。