hashmap,hashset,hashtable区别

来源:互联网 发布:java post body json 编辑:程序博客网 时间:2024/06/05 15:22

作为一个比较经典的面试题。从伯乐在线看到了几个比较经典的文章

引用链接:

http://www.importnew.com/7099.html

这篇文章讲的是hashmap面试用的一些问题。

引申到java最底层的equals 和 hashcode()方法。

hashcode一样,equals不一定一样,但equals一样,hashcode一定一样!

默认情况下。equals为直接 this == obj 进行对比,而hashcode()为底层调用其他方法进行实现。


那么 hashmap基于hashing原理,键值对存储模式,为集合类的一个具体实现类。

当hashmap 存键值对时,这里为map.entry.也就是put(k,v)时,从源码来看,但调用put方法时,

首先判断key是否为空,hashmap允许为null,return putfornullKey(v);

public V put(K key, V value) {// 处理key为null,HashMap允许key和value为nullif (key == null)return putForNullKey(value);// 计算key值的hash int hash = hash(key);// 通过哈希码计算出bucketIndexint i = indexFor(hash, table.length);// 取出bucketIndex位置上的元素,并循环单链表,判断key是否已存在for (Entry<K,V> e = table[i]; e != null; e = e.next) {Object k;// 哈希码相同并且对象相同时if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {// 新值替换旧值,并返回旧值V oldValue = e.value;e.value = value;e.recordAccess(this);return oldValue;}}// key不存在时,加入新元素modCount++;addEntry(hash, key, value, i);return null;}
计算出key的hash,通过hash计算出bucketIndex这个位置,,因为k.v键值对都存放在hashmap里一个叫做bucket的地方,一个bucket作为一个map.entry来取对象,这是取对象迭代器的逻辑。

判断,这个位置如果没元素,直接添加,如果有元素 循环这个位置的元素的key,如果 hash相同 并且equals相同时,新V替换旧V,如果hash相同,但是equals不相同时,这就是碰撞现象,因为hashmap是通过链表来维护键值对的,所以在这个bucket里面有有一个单链表去维护这些键值对。将新元素(新的map.entry)加入到表头。

那么出现碰撞的话,取得时候怎么办呢。取用的是 get方法 通过key的hash获取到bucket然后遍历所有元素,通过equals方法来判断自己真正想要的值。

为了尽量避免发生碰撞现象,尽量使用string,integer这种不可变的final类型的作为Key,也可以使用自定义的对象,只要能保证对象不可变就是了。

当hashmap的负载因子达到总体容量的75%时,会默认扩充到本身的两倍。因为hashmap本身为非同步的,线程不安全类型,在保证了速度的同时,牺牲了安全性,导致容易在多线程的情况下,多个线程同时进行对一个hashmap进行扩容的情况,这种现象叫做条件竞争,因为在扩容的同时,里面存在的元素会放到整个map的头部,这是为了避免尾部遍历,所以容易导致死循环。那么这种多线程的情况下。为什么要用 非线程安全的hashmao????

hashmap hashtable的区别

都继承了map,更多的区别表现在,线程安全性,速度 和 同步上

在存储上,两者基本相同,hashmap只是多了允许存放null的键值对上。同时,他的元素存放顺序是不一定的!

在线程安全性上,hashmap为非安全,table反之,多个线程是允许共享一个table的,但如果没有安全的同步情况下,hashmap是不安全的,同时在jdk1.5之后出现了一个concrrenthashmap,他是table的代替品,有更好的扩展性!

在速度上,因为hashmap的非安全性,导致了在单线程下他的速度比table要快。


hashmap hashset的区别

                        hashmap,          hashset

接口                  map                                     set

                    键值对存储                           对象存储

            存储时以key来hashcode       存储时以对象来hashcode

                    速度稍比hashset快



0 0