首页

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

标签:TreeSet,ArrayList,HashSet,Vector,ConcurrentLinkedQueue,源码剖析     发布时间:2015-07-20   

一、前言

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

ArrayList源码:

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

HashSet源码:

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

 

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

Vector源码:

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

ConcurrentLinkedQueue源码:

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

所以只要定义对象唯一性属性,然后重写父类Object的equals方法中判断唯一性属性就可以了,如下定义obj类,并定义属性a、b值都相等时对象才认为值相等,代码如下:

class obj implements Comparable<obj>{@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<obj> treeSet=new TreeSet<obj>();@b@    public  List<obj> arrayList=new ArrayList<obj>();@b@    public HashSet<obj> hashSet=new HashSet<obj>();@b@    public Vector<obj> vector=new Vector<obj>();@b@    public Queue<obj> queue=new ConcurrentLinkedQueue<obj>();@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进行存储实现,源码对照分析

2015-07-20_230010.jpg

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

2015-07-20_231023.jpg

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

2015-07-20_231350.jpg

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

2015-07-20_231650.jpg

因此,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等)可以不考虑大小

@b@
<<热门下载>>