Hashtable、Hashset傻傻分不清?
其实本来说不写这两个类了,但是跟一块心病似的。还是写了吧,把这些不太熟的犄角旮瘩都打扫一遍!
Hashtable
public class Hashtable<K,V>
extends Dictionary<K,V>
implements Map<K,V>, Cloneable, java.io.Serializable {
Dictionary是一个废弃类,就不关注它了。可以看到还实现了Map接口,所以是一个键值对结构。Map中无非就是些增删查改的APi,不再赘述。
private transient Entry<?,?>[] table;
private transient int count;
private int threshold;
private float loadFactor;
protected Entry(int hash, K key, V value, Entry<K,V> next) {
this.hash = hash;
this.key = key;
this.value = value;
this.next = next;
}
public V setValue(V value) {
if (value == null)
throw new NullPointerException();
}
可以看到基本结构与hashmap一致,底层就是哈希桶,哈希桶中每个桶都是链表,与hashmap的不同就是这里的entry中的value不能为空,会抛出NPE。
其实hashtable真挺没劲的,相关方法都跟hashmap类似,但是都没hashmap写得好。。hashtable想比hashmap唯一的优点可能就是线程安全,每个操作方法都被synchronized锁住了,可是这一锁就把整个entry数组锁住了,锁的粒度太大了,并发性远不如Concurrenthashmap来的好,所以,给个结论,hashtable这玩意儿已经废弃了。。。既没concurrenthashmap好用,也没hashmap来的巧妙。
Hashset
public class HashSet<E>
extends AbstractSet<E>
implements Set<E>, Cloneable, java.io.Serializable
可以看到hashset就是个set,即里边没有重复元素
private transient HashMap<E,Object> map;
private transient HashMap<E,Object> map;
private static final Object PRESENT = new Object();
public HashSet() {
map = new HashMap<>();
}
其内部就是个hashmap,一旦初始化就也将hashmap初始化。这也是其设计巧妙之处,通过hashmap实现元素的唯一性,即每个加入进来的元素都作为key放入hashmap,相对应的value就是这里的PRESENT,即每个元素都是key,value是同一个值。
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
hashmap的put函数会返回该key对应的原来的value,如果原来value不是空,说明对应位置本来就有值,即我们正在加入重复值,返回false,以此来保证hashset中的元素的不可重复。
其他各项方法也是类似,其实就是hashset中包着一层hashmap,巧妙地实现set的不可重复。
公众号:程序员二狗
每日原创文章,一起交流学习!
推荐阅读
-
面粉和淀粉的区别是什么,别再傻傻分不清了
-
java中集合(LinkedList、HashSet、HashMap、HashTable、Collection、Collections)
-
java语法ArrayList、LinkedList、HashSet、HashMap、HashTable、Collection、Collections详解
-
猕猴桃奇异果的区别,别再傻傻的分不清了
-
手机LPDDR5和LPDDR4X内存还傻傻分不清?带你一文看懂
-
张飞和李逵别再傻傻的分不清了 看看这些就知道了
-
西红柿蔬菜还是水果,傻傻分不清楚
-
Java中Integer.parseInt和Integer.valueOf,你还傻傻分不清吗?
-
椰皇和椰青的区别,你到现在都还傻傻分不清楚吗?赶紧看过来吧!
-
老虎,老鼠,傻傻的分不清楚。