首页 » IT技术 » 正文

重新分析List集合去重,那些隐藏的坑

前言:
网上这类方法很多,但是,大多数都是坑,那些方式大多只能处理集合中对象为简单类型的集合,如果集合中是自定的类,网上的方法大多数会挂掉。
分析:

如果要对一个List集合中的元素去除重复,一般思路是定义一个方法,这个方法中定义一个新的集合,遍历原来的集合,将原来集合中的元素一个一个加入到新的集合中,例如:
在加入的时候使用集合的contains方法判断集合中是否已经包含了这个元素,如果包含则不再添加。
但是在实际过程中,contains方法并不能正确的判断,因为,contains方法内部使用的集合中元素的equals方法,如果这个List中的对象是基本类型,没有什么问题,但是
如果集合中的对象是引用对象,那么使用该对象的equals方法,就会出现问题,因为自己定义的引用对象equals方法继承的Object类中的equals方法,这个方法比较的是对象的内存地址,一般情况下我们多使用new 方式创建一个引用对象,即使对象内容完全一样,也会在内存中存在一个新的实体,内存地址也完全不同。
所以要使用以下方法解决这个问题。

思路:重新自定义对象中的equals方法

如下:

 
重新对象中的equals 方法,比较传入的对象内容是否和当前对象的内容一致。

源代码   
import java.util.*;
class Person{
private String name;
private int age;
Person(String name,int age){
this.name=name;
this.age=age;
}
public void setName(String name){
this.name=name;
}
public void setAge(int age){
this.age=age;
}
public String getName(){
return this.name;
}
public int getAge(){
return this.age;
}
//这里重写equals 方法,比较传入的对象内容是否和当前对象的内容一致。
public boolean equals(Object obj){
if (!(obj instanceof Person))
return false;
Person p=(Person)obj;
return this.age==p.getAge() && this.name.equals(p.getName());
}
}
class ArrayListEquals{
public static void main(String arg[]){
List<Person> al=new ArrayList<Person>();
al.add(new Person("张三",18));
al.add(new Person("张三",18));
al.add(new Person("李四",12));
al=singleList(al); //去除重复
for(int i=0;i<al.size();i++){
Person p=al.get(i);
System.out.println("name:"+p.getName()+" age:"+p.getAge());
}
//****以上引用数据类型需要在对象中重新equals方法*分割线 *以下基本数据类型没有问题******
List<String> al1=new ArrayList<String>();
al1.add("张三");
al1.add("张三");
al1.add("李四");
al1=singleList(al1); //去除重复
for(int i=0;i<al1.size();i++){
System.out.println("name:"+al1.get(i));
}
}
//去除重复的方法
private static List singleList(List list){
List templist =new ArrayList();
for (Iterator it=list.iterator();it.hasNext();){
Object obj=it.next();
if(!templist.contains(obj)) // 这个方法内部用的是集合中元素的equals方法。
templist.add(obj);
}
return templist;
}
}

下面是一些类似的代码,经过验证,如果不在自定义的对象中重新equals方法,下面的方法对集合中是自定对象的集合是无效的。

1. 循环list中的所有元素然后删除重复 只能针对集合类型为简单数据类型的集合有效

源代码   
public   static   List  removeDuplicate(List list)  {       
  for  ( int  i  =   0 ; i    i; j -- )  {       
           if  (list.get(j).equals(list.get(i)))  {       
              list.remove(j);       
            }        
        }        
      }        
    return list;       
}  

2. 通过HashSet踢除重复元素 只能针对集合类型为简单数据类型的集合有效
源代码   
public static List removeDuplicate(List list) {   
HashSet h = new HashSet(list);   
list.clear();   
list.addAll(h);   
return list;   
}   

3. 删除ArrayList中重复元素,保持顺序 只能针对集合类型为简单数据类型的集合有效 
源代码   
 public static void removeDuplicateWithOrder(List list) {    
    Set set = new HashSet();    
     List newList = new ArrayList();    
   for (Iterator iter = list.iterator(); iter.hasNext();) {    
         Object element = iter.next();    
         if (set.add(element))    
            newList.add(element);    
      }     
     list.clear();    
     list.addAll(newList);    
    System.out.println( " remove duplicate " + list);    
 }   

发表评论