思路:创建一个新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 |
去重成功。