HashMap与HashTable、HashSet的区别

HashTable和HashMap区别
区别一:继承的父类不同 
Hashtable继承自Dictionary类,而HashMap继承自AbstractMap类。但二者都实现了Map接口。

public class Hashtable<K,V> extends Dictionary<K,V>  
implements Map<K,V>, Cloneable, Serializable  
 
public class HashMap<K,V> extends AbstractMap<K,V>  
implements Map<K,V>, Cloneable, Serializable 
区别二:线程安全性不同,Hashtable是线程安全,而HashMap则非线程安全
Hashtable的实现方法里面都添加了synchronized关键字来确保线程同步,因此相对而言HashMap性能会高一些,我们平时使用时若无特殊需求建议使用HashMap,在多线程环境下若使用HashMap需要使用Collections.synchronizedMap()方法来获取一个线程安全的集合(Collections.synchronizedMap()实现原理是Collections定义了一个SynchronizedMap的内部类,这个类实现了Map接口,在调用方法时使用synchronized来保证线程同步,当然了实际上操作的还是我们传入的HashMap实例,简单的说就是Collections.synchronizedMap()方法帮我们在操作HashMap时自动添加了synchronized来实现线程同步,类似的其它Collections.synchronizedXX方法也是类似原理)

区别三:是否提供contains方法 
HashMap把Hashtable的contains方法去掉了,改成containsValue和containsKey,因为contains方法容易让人引起误解。 
Hashtable则保留了contains,containsValue和containsKey三个方法,其中contains和containsValue功能相同。

区别四:**key和value是否允许null值 
其中key和value都是对象,并且不能包含重复key,但可以包含重复的value。 
Hashtable中,key和value都不允许出现null值。 
HashMap中,null可以作为键,这样的键只有一个;可以有一个或多个键所对应的值为null。当get()方法返回null值时,可能是 HashMap中没有该键,也可能使该键所对应的值为null。因此,在HashMap中不能由get()方法来判断HashMap中是否存在某个键, 而应该用containsKey()方法来判断。 
PS:这个面试喜欢问。

区别五:哈希值的计算方法不同,Hashtable直接使用的是对象的hashCode,而HashMap则是在对象的hashCode的基础上还进行了一些变化。

//Hashtable中可以看出的是直接采用关键字的hashcode作为哈希值
    int hash = key.hashCode();
    //然后进行模运算,求出所在哗然表的位置 
    int index = (hash & 0x7FFFFFFF) % tab.length;
//HashMap中的实现
   //这两行代码的意思是先计算hashcode,然后再求其在哈希表的相应位置      
    int hash = hash(key.hashCode());
    int i = indexFor(hash, table.length);
    static int hash(int h) {
     // This function ensures that hashCodes that differ only by
     // constant multiples at each bit position have a bounded
     // number of collisions (approximately 8 at default load factor).
        h ^= (h >>> 20) ^ (h >>> 12);
        return h ^ (h >>> 7) ^ (h >>> 4);
    }
   //求位于哈希表中的位置
    static int indexFor(int h, int length) {
        return h & (length-1);
    }
区别六:内部实现使用的数组初始化和扩容方式不同,内存初始大小不同,HashTable初始大小是11,而HashMap初始大小是16

 public Hashtable() {
                //从这里可以看出,默认的初始化大小11,
                //这里的11并不是11个字节,而是11个       Entry,这个Entry是
                //实现链表的关键结构
                //这里的0.75代表的是装载因子
                this(11, 0.75f);
     }
    public HashMap() {
        //这个默认的装载因子也是0.75
         this.loadFactor = DEFAULT_LOAD_FACTOR;
        //默认的痤为0.75*16
        threshold = (int)(DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR);
        //这里开始是默认的初始化大小,这里大小是16
        table = new Entry[DEFAULT_INITIAL_CAPACITY];
        init();
    }
Hashtable采用的是2*old+1,而HashMap是2*old

HashMap和HashSet的区别
面试中经常被问到HashMap与HashSet的区别。于是本渣静下心来总结了一下HashSet与HashMap的区别。

  先了解一下HashMap跟HashSet

 HashSet:

  HashSet实现了Set接口,它不允许集合中出现重复元素。当我们提到HashSet时,第一件事就是在将对象存储在

HashSet之前,要确保重写hashCode()方法和equals()方法,这样才能比较对象的值是否相等,确保集合中没有

储存相同的对象。如果不重写上述两个方法,那么将使用下面方法默认实现:

 public boolean add(Object obj)方法用在Set添加元素时,如果元素值重复时返回 "false",如果添加成功则返回"true"

HashMap:

  HashMap实现了Map接口,Map接口对键值对进行映射。Map中不允许出现重复的键(Key)。Map接口有两个基本的实现

TreeMap和HashMap。TreeMap保存了对象的排列次序,而HashMap不能。HashMap可以有空的键值对(Key(null)-Value(null))

HashMap是非线程安全的(非Synchronize)

我们能否让HashMap同步?
HashMap可以通过下面的语句进行同步:
Map m = Collections.synchronizeMap(hashMap);

public Object put(Object Key,Object value)方法用来将元素添加到map中。

HashSet与HashMap的区别:

HashMap    HashSet
实现了Map接口    实现Set接口
存储键值对    仅存储对象
调用put()向map中添加元素    调用add()方法向Set中添加元素
HashMap使用键(Key)计算Hashcode    
HashSet使用成员对象来计算hashcode值,

对于两个对象来说hashcode可能相同,

所以equals()方法用来判断对象的相等性,

如果两个对象不同的话,那么返回false

HashMap相对于HashSet较快,因为它是使用唯一的键获取对象    HashSet较HashMap来说比较慢

————————————————
版权声明:本文为CSDN博主「斯维特哈特」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_24309787/article/details/88950246

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值