contains java源码实现,关于jdk实现类集中判断对象是否已存在contains方法源码分析对比...

一、前言

jdk对于大部分类(ArrayList、HashSet、Vector、ConcurrentLinkedQueue)集实现判断contains方法,都是遍历类集对象进行比较是否相等(equals值是否相等),源码分析如下:

ArrayList源码:

93a8fb272d0e91414a9a57de8dfa3eac.png

HashSet源码:

05b597f2005b90a8b2614ee3bbae6415.png

942137845735234e34234fb127053443.png

Vector源码:

19f821d15f3a7bb2f52b2e4fc5069b90.png

ConcurrentLinkedQueue源码:

86da63242611f4b65be63ecf8ad0a3a7.png

所以只要定义对象唯一性属性,然后重写父类Object的equals方法中判断唯一性属性就可以了,如下定义obj类,并定义属性a、b值都相等时对象才认为值相等,代码如下:class obj implements Comparable{@b@    @b@    private String a;@b@    private String b;@b@    @b@    public obj() {@b@        super();@b@    }@b@    @b@    public obj(String a, String b) {@b@        super();@b@        this.a = a;@b@        this.b = b;@b@    }@b@    public String getA() {@b@        return a;@b@    }@b@    public String getB() {@b@        return b;@b@    }@b@    public void setA(String a) {@b@        this.a = a;@b@    }@b@    public void setB(String b) {@b@        this.b = b;@b@    }@b@    @Override@b@    public int compareTo(obj o) {@b@        // TODO Auto-generated method stub@b@        return 0;@b@    }@b@    @Override@b@    public boolean equals(Object o) {@b@        // TODO Auto-generated method stub@b@        obj _this=(obj)o;@b@        if(_this==null)@b@            return false;@b@        if(!this.getA().equals(_this.getA()))@b@            return false;@b@        if(!this.getB().equals(_this.getB()))@b@            return false;@b@        return true;@b@    }@b@    @b@}

但是有少部分实现的类集 contains方法是没有办法判断是否包含该对象的,如TreeSet

二、对比测试

下面代码对ArrayList、HashSet、Vector、ConcurrentLinkedQueue测试对比,示例代码如下:import java.util.ArrayList;@b@import java.util.HashSet;@b@import java.util.List;@b@import java.util.Queue;@b@import java.util.TreeSet;@b@import java.util.Vector;@b@import java.util.concurrent.ConcurrentLinkedQueue;@b@@b@/**@b@ *  类描述@b@ * @author nijun@b@ * @version 版本创建于  2015-7-20@b@ */@b@@b@public class ContainsSetTest {@b@    @b@    public  TreeSet treeSet=new TreeSet();@b@    public  List arrayList=new ArrayList();@b@    public HashSet hashSet=new HashSet();@b@    public Vector vector=new Vector();@b@    public Queue queue=new ConcurrentLinkedQueue();@b@    @b@    @b@    public static void main(String[] args) {@b@        @b@        /**TreeSet contains Test*/@b@        ContainsSetTest test=new ContainsSetTest();@b@        obj o1=new obj("11","111");@b@        obj o2=new obj("22","222");@b@        test.treeSet.add(o1);@b@        if(!test.treeSet.contains(o2))@b@            test.treeSet.add(o2);@b@        System.out.println("TreeSet.contains()->size:"+test.treeSet.size());@b@        @b@        /**ArrayList contains Test*/@b@        test.arrayList.add(o1);@b@        if(!test.arrayList.contains(o2))@b@            test.arrayList.add(o2);@b@        System.out.println("ArrayList.contains()->size:"+test.arrayList.size());@b@        @b@        @b@        /**HashSet contains Test*/@b@        test.hashSet.add(o1);@b@        if(!test.hashSet.contains(o2))@b@            test.hashSet.add(o2);@b@        System.out.println("HashSet.contains()->size:"+test.hashSet.size());@b@        @b@        @b@        /**Vector contains Test*/@b@        test.vector.add(o1);@b@        if(!test.vector.contains(o2))@b@            test.vector.add(o2);@b@        System.out.println("Vector.contains()->size:"+test.vector.size());@b@        @b@        @b@        /**ConcurrentLinkedQueue contains Test*/@b@        test.queue.add(o1);@b@        if(!test.queue.contains(o2))@b@            test.queue.add(o2);@b@        System.out.println("ConcurrentLinkedQueue.contains()->size:"+test.queue.size());@b@        @b@    } @b@}

运行结果TreeSet.contains()->size:1@b@ArrayList.contains()->size:2@b@HashSet.contains()->size:2@b@Vector.contains()->size:2@b@ConcurrentLinkedQueue.contains()->size:2

三、对比分析

TreeSet是只能存大小不一样的对象,如大小一样则只能保留最开始的那个对象,其实基于TreeMap进行存储实现,源码对照分析

0a00acdc5e6bfa26ca9ad23279cbe438.png

打开NavigableMap接口实现类在TreeMap匿名类NavigableSubMap中,其containsKey方法如下(对于判断在范围的情况下,再通过TreeMap的containsKey去找)

28bcf806e0632b05723c7f25c064668d.png

TreeMap的containsKey方法,直接判断获取实体对象是否为空,不为空及存在这样的对象

80c4e94ad264ca53fe7b427521f04ee4.png

TreeMap的getEntry方法还是最终比较对象大小,如果一样,就直接拿值相等的对象,否则拿前一个或者后一个

7d7ccc7f5c5bad5e00de243420247fd8.png

因此,Comparable的compareTo方法必须重新,修改类obj的compareTo方法如下:@Override@b@    public int compareTo(obj o) {@b@        // TODO Auto-generated method stub@b@        return o.getA().compareTo(this.getA());@b@    }

再运行结果,就正常了TreeSet.contains()->size:2

三、总结

因此对于TreeSet只能保存大小不一样的对象集合,必须重写compareTo方法以定义对象之间大小,如果实际对象没有大小,将不能存储下来,其他大部分类集(ArrayList、HashSet、Vector、ConcurrentLinkedQueue等)可以不考虑大小

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值