阅读源码是和大师面对面交流的机会之ArrayList检查是否有重复元素

    List是允许存在重复元素的,同样ArrayList也允许。那么ArrayList是如何检测是否存在重复元素的?下面我们浅读一下源码:

    /**
         * 判断列表是否包含某对象
         * @param o
         * @return
     */
    public boolean contains(Object o){
        return indexOf(o)>=0;
    }   
contains()方法会返回是boolean,会告诉你是否存在该元素。元素是否重复的具体判断方法是indexOf():
     /**
     * 判断对象是否存在与某个列表中
     * 大多数情况下不能满足需求,实体对象的比较往往需要重写equals方法去直接比较对象的属性
     * @return
     */
    public int indexOf(Object objec){
        if(objec == null){
            for(int i=0;i<size;i++){
                if(elementData[i]==null){
                    return i;
                }
            }
        }else{
            for(int i=0;i<size;i++){
                if(objec.equals(elementData[i]))
                    return i;
            }
        }
        return -1;
    }   
    在源码中可以看出,indexOf对null对象也会进行比较,非空对象则会调用所有对象都具有的方法:equals()进行是否重复的比较。
但是有个问题,就是equals()方法对一些基本类型的比较可以返回较为真的值,但是对于一些entity对象就不行了,比如下面的这例子:  
public class User{  
        private int id;
        private String name;
    }
@Test
public class Test {
        ArrayList<User> userList= new ArrayList<User>();
        User user1 = new User(1,"小明");
        User user2 = new User(1,"小明");
        userList.add(user1);
        //userList.add(user2);
        System.out.println(userList.contains(user2));
   }
    输出是false,但是在实际的业务逻辑中,此处应该返回的是true,因为我们用new在内存中开辟了两个对象空间,而对象自带的equals方法会对对象的引用地址进行比较,所以得出了两个对象虽然属性相等但却不重复的结果,这时候就需要我们重写对象的equals方法,具体的实现就是直接拿对象的属性值来比较:
public boolean equals(Object obj) { 
        if(this ==obj){
            return true;            
        } if (obj!=null && obj instanceof User) {//判断obj是否是User的一个实例
            User u = (User) obj;   //强制转换
            return this.id==u.id&&this.name.equals(u.name);   //直接比较属性值
        }else{
            return false;
        }
    }
    这样的equals方法对于对象的比较才有实际意义,当我们在采用ArrayList装载对象时,可以采用这种方式来判断是否有重复对象。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值