A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 泮和顺 中级黑马   /  2012-3-19 19:06  /  2371 人查看  /  7 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

hashset底层实现机制由hashtable实现  但是明显hashtable还要复杂些 怎么个实现法呢 ???hashtable跟hashmap差不多 一个同步一个异步

7 个回复

倒序浏览
本帖最后由 陈从宾 于 2012-3-19 19:14 编辑

对于HashSet而言,它是基于HashMap实现的,HashSet底层使用HashMap来保存所有元素,因此HashSet 的实现比较简单,相关HashSet的操作,基本上都是直接调用底层HashMap的相关方法来完成,HashMap实际上是一个“链表散列”的数据结构,即数组和链表的结合体。
回复 使用道具 举报
hashSet是一个单列表集合,hashtable是一个双列表集合,双列表集合的底层就是相对应的单列表集合构成的。有的时候可以把双列表看成是单列表,比如双列表集合中存放的键值,可以封装成一个对象
回复 使用道具 举报
李飞 发表于 2012-3-19 19:22
hashSet是一个单列表集合,hashtable是一个双列表集合,双列表集合的底层就是相对应的单列表集合构成的。有 ...

这样说的也对的
但是底层是有一张hashtable是底层系统做好的 而hashset存放元素的时候根据这个表来存元素 应该是这样吧
回复 使用道具 举报
集合排序总结
        list: 元素是有序的,元素可以重复,因为该集合体系有索引(脚标)
            常用的子类对象:     面试题重点
                ArrayList 底层的数据结构是使用的数组结构 特点:查询速度快,但是增删比较慢
                LinkedList底层的数据结构使用的是链表结构 特点:增删速度快,但是查询比较慢
            Vector          底层是数组数据结构。线程同步,ArrayList线程不同步,替代了vector  
ArrayList 是可变长度数组,默认长度是10,当添加的元素大于10时,系统自动new一个新的数组且增长原数组的一半长度,并把之前的元 素复制到这个新数组中,vector和它一样,但是延长一倍。
Set:无序,不可重复元素
                   HashSet: 数据结构是哈希表,线程是非同步的。
                                  保证元素唯一性的原理,判断元素的hashCode值是否相同
                                  如果相同,还会继续判断元素的equals方法,是否为true。
                TreeSet: 可以对Set集合中的元素进行排序。底层数据结构是二叉树。
                                  保证元素唯一行的依据,compareTo方法return 0;
                   TreeSet 排序的第一种方式
                               让元素(对象)自身具备比较性。元素需要实现Comparable接口,覆盖
                                   compareTo方法这种方式也称为元素的自然顺序,或者叫做默认顺序
                   TreeSet第二种排序方式:
                           当元素自身不具备比较性时,或者具备的比较性不是所需要
                           的,这时需要让集合(TreeSet)自身具备比较性。
                           做法是在集合初始化时,就有了比较方式,即定义一个比较器
                           将比较器作为参数传递给TreeSet集合的构造函数。
                           比较器--定义一个类,实现Comparator接口,覆盖compare方法。
                                   而当两种排序都存在时以比较器为主

关于ArrayList添加对象,自定义判断条件问题以及HashSet集合添加自定义对象问题
虽然两个集合的底层结构不同,但是他们都调用添加对象类中的equals方法,而
       
        ArrayList是通过contains()方法让系统自动调用equals方法
       
        HashSet是通过当add添加元素的时候 系统自动调用hashCode()方法判断hash值
        如果相等则不会被添加,如果相等,再通过hashCode方法调用equals方法判断。
        一般添加的时候都会在类中重写hashCode 和equals以满足实际条件的需求。
        但是,ArrayList和HashSet重写Object类中的equals方法原理都是一样的。
例如:                       
class Person
{
        private String name;
        private int age;
        Person(String name,int age)
        {
                this.name=name;
                this.age=age;
        }
        public String getName()
        {
                return name;
        }
        public int getAge()
        {
                return age;
        }
此equals是重写Object中的equals方法
obj形参 实参是contains中的,相当于obj=new Person("xiaoxiao11",15); 多态
        public boolean equals(Object obj)
        {
               
判断传进来的对象是否是Person对象 不是的话就返回false
                if (!(obj instanceof Person))  
                {
                        return false;
                }

因为穿参传进来的对象是Object的子类对象,体现多态性,必须向下转型
                Person p=(Person)obj;
       
                return this.name.equals(p.name)&&this.age==p.age;   
而return中的equlas是字符串中的equals方法~~! 比较字符串对象的内容是否相同
        }

}
关于TreeSet添加自定意对象,让其排序的问题。有两种方式

        第一种   让元素(对象)自身具备比较性。元素需要实现Comparable接口,覆盖
                         compareTo方法这种方式也称为元素的自然顺序,或者叫做默认顺序
                        class Student implements Comparable<Student>
                        {
                                private String name;
                                private int age;
                                Student(String name,int age)
                                {
                                        this.name=name;
                                        this.age=age;
                                }
                当在TreSet中添加对象的时候底层自动调用Comparable接口中的compareTo方法
                class Student implements Comparable <Student>
                {
                        private String name;
                        private int age;
                        Student(String name,int age)
                        {
                                this.name=name;
                                this.age=age;
                        }
                        public int compareTo(Student s)
                        {
                                System.out.println(this.name+"...compareto...."+s.name);
                                int num= new Integer(this.age).compareTo(new Integer (s.age));
                                if(num==0)       
                                        return this.name.compareTo(s.name);//比较名字是否相同时次要条件
                                return num;
                        }

                        public String getName()
                        {
                                return name;
                        }
                        public int getAge()
                        {
                                return age;
                        }
                }
第二种:    当元素自身不具备比较性时,或者具备的比较性不是所需要的,这时需要让
                    集合(TreeSet)自身具备比较性。做法是在集合初始化时,就有了比较方式,
                    即定义一个比较器将比较器作为参数传递给TreeSet集合的构造函数。
                    比较器--定义一个类,实现Comparator接口,覆盖compare方法。
                    而当两种排序都存在时以比较器为主
                        使用了泛型--在集合初始化时把new Mycomparator()以构造方法传参传进去即可
                        class Mycomparator implements Comparator<String>
                        {
                                public int compare(String o1,String o2)       
                                {

                                        int num=new Integer(o1.length()).compareTo(new Integer (o2.length()));
                                        if (num==0)
                                        {
                                                return         o1.compareTo(o2);
                                        }
                                        return num;
                                }
                        }

Map集合的两种取出方式       
        Set<k> keySet:将Map中所有的键存入到Set集合,因为Set集合具备迭代器
                                  所以可以迭代取出所有的键,在根据get(key)获取值。
                                  Map集合的取出原理:将Map集合转成Set集合,再迭代取出。
       
        Set<Map.Entry<k,v>> entrySet:将Map集合中的映射关系存入到Set集合中,
                                                        而这个关系的数据类型就是:Map.Entry
        Map.Entry 其实Entry也是一个就扣,它是Map接口中的一个内部接口。
        interface Map
        {
                public static interface Entry
                {        定义内部接口是因为取出Map中的成员属性方便
                        public abstract Object getKey();
                        public abstract Object getValue();
                }

        }
        class HashMap implements Map
        {  //HashMap 取出元素的原理
                class Haha implements Map.Entry
                {  
                        public abstract Object getKey(){  }
                        public abstract Object getValue(){  }
                }

Map的子类
                Hashtable:底层是哈希表数据结构,不可以存null键null值。线程同步
                HashMap:  底层是哈希表数据结构,允许存null键null值,线程不同步
                TreeMap:  底层是二叉树数据结构,线程不同步,可以给Map中的键排序
                                  其实Set底层就是使用了Map集合。
Map集合的两种取出方式       
        Set<k> keySet:将Map中所有的键存入到Set集合,因为Set集合具备迭代器
                                  所以可以迭代取出所有的键,在根据get(key)获取值。
                                  Map集合的取出原理:将Map集合转成Set集合,再迭代取出。
       
        Set<Map.Entry<k,v>> entrySet:将Map集合中的映射关系存入到Set集合中,
                                                        而这个关系的数据类型就是:Map.Entry
        Map.Entry 其实Entry也是一个就扣,它是Map接口中的一个内部接口。
        interface Map
        {
                public static interface Entry
                {        定义内部接口是因为取出Map中的成员属性方便
                        public abstract Object getKey();
                        public abstract Object getValue();
                }

        }
        class HashMap implements Map
        {  //HashMap 取出元素的原理
                class Haha implements Map.Entry
                {  
                        public abstract Object getKey(){  }
                        public abstract Object getValue(){  }
                }
        }

        }

回复 使用道具 举报
贠(yun)靖 发表于 2012-3-19 19:51
集合排序总结
        list: 元素是有序的,元素可以重复,因为该集合体系有索引(脚标)
            常用的子类对象:   ...

做总结当万能公式一样不好吧。。。
回复 使用道具 举报
王思兰 黑马帝 2012-3-19 20:04:29
7#
HashMap 是Hashtable 的轻量级实现(非线程安全的实现),他们都完成了Map 接口,主要
区别在于HashMap 允许空(null)键值(key),由于非线程安全,效率上可能高于Hashtable。
HashMap 允许将null 作为一个entry 的key 或者value,而Hashtable 不允许。
HashMap 把Hashtable 的contains 方法去掉了,改成containsvalue 和containsKey。因为contains
方法容易让人引起误解。
Hashtable 继承自Dictionary 类,而HashMap 是Java1.2 引进的Map interface 的一个实现。
最大的不同是,Hashtable 的方法是Synchronize 的,而HashMap 不是,在多个线程访问
Hashtable 时,不需要自己为它的方法实现同步,而HashMap 就必须为之提供外同步。
Hashtable 和HashMap 采用的hash/rehash 算法都大概一样,所以性能不会有很大的差异。
回复 使用道具 举报
本帖最后由 贠(yun)靖 于 2012-3-19 20:25 编辑
泮和顺 发表于 2012-3-19 19:57
做总结当万能公式一样不好吧。。。


呵呵,你以为我是为了分么?  还不至于。  仅仅是想分享一下,你既然这么认为~~~! 好吧,自作多情了~~~!
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马