面试Java基础之HashMap、Hashtable、WeakHashMap比较

时间:2022-01-12 16:47:43

在Java面试中,有关集合框架常见问题就经常出现HashMap和HashTable的比较。主要是为了用来考验程序员是否能够正确使用集合类以及是否可以随机应变使用多种思路解决问题。

Map
├Hashtable
├HashMap
└WeakHashMap

  • Hashtable是Dictionary的子类
 public class Hashtable<K, V> extends Dictionary<K, V> implements Map<K, V>, Cloneable, Serializable {}
  • HashMap是AbstractMap一个实现类
public class HashMap<K, V> extends AbstractMap<K, V> implements Cloneable, Serializable {}
public abstract class AbstractMap<K, V> implements Map<K, V> {}

通过继承关系,我们可以看到HashMap和Hashtable都实现了Map接口。那Map接口到底是何方神圣?俩个类都实现他呢?

Map是没有持续Collection接口,是用于保存具有映射关系的数据(key-vlaue)。Map供给key到value的映射,Map的key不允许重复,每个key只能映射一个value。即同一个Map对象的任何两个key通过equals方法比较总是返回false,Map中包含了一个keySet()方法,用于返回Map所以key组成的Set集合。笼统地说Map接口其实可以说包含了三个集合,一组key-value集合、一组key集合以及value集合。 Map是键到值的映射,Java集合框架在实现上采用一个个Map.Entry内部类来封装每一个键值对,这样,Map中的元素就变成了Map.Entry的集合。

  • HashMap类
    HashMap允许键(key)和值(value)为空(null),null可以作为键,这样的键只有一个,但可以有一个或多个键所对应的值为null,这里有个需要注意的是,但我们用get()方法返回null值时,即可以表示HashMap中没有该键,也可以表示该键所对应的值为null。因此,在HashMap中不能由get()方法来判断HashMap中是否存在某个键,而应该用containsKey()方法来判断。HashMap是非synchronized(非线程安全的实现),如果涉及到多个线程,那就不应该考虑使用HashMap。但是Java 5提供了ConcurrentHashMap,它比HashTable的扩展性更好、性能更高。HashMap可以通过下面的语句进行同步:Map map = Collections.synchronizeMap(hashMap);

  • Hashtable类
    HashTable不允许有null的键(key)和值(value),HashTable是synchronized(线程安全实现),这意味着HashTable是线程安全的,多个线程可以共享一个HashTable。上面提到ConcurrentHashMap到底和Hashtable有啥不一样,笔者也查阅下相关知识,主要Hashtable的实现方式是锁整个hash表,而ConcurrentHashMap分段式*,分层多个节点进行关键部位加锁,避免大锁,允许多个修改操作并发进行。具体可以了解Java集合—ConcurrentHashMap原理分析

  • WeakHashMap类
    WeakHashMap是一种改进的HashMap,它对key实验“弱引用”,若是一个key不再被外部所引用,那么该key可以被GC收受接管。

  • hashCode和equals方法
    如果涉及使用对象作为key,那么key的对象都必须实现hashCode和equals方法。hashCode和equals方法持续自根类Object,若是你用自定义的类算作key的话,就需要同时复写equals办法和hashCode方法,因为我们java的集合中判断两个对象是否相等,是根据hashCode和equals这个俩个方法。规则是先判断两个对象的hashCode是否相等,如果不相等,认为两个对象也不相等,如果相等,再判断两个对象用equals运算是否相等。如果不相等,认为两个对象也不相等,如果相等,认为两个对象相等。

    • hashCode方法,返回该对象的哈希码值。用哈希函数来计算散列值以实现哈希表这种数据结构。hashCode用来提高Map里面的搜索效率的,Map会根据不同的hashCode来放在不同的位置,Map在搜索一个对象的时候先通过hashCode找到相应的位置,然后再根据equals方法判断这个位置上的对象与当前要插入的对象是不是同一个。其实hashCode用来定位要存放的位置。我们可以通过重载hashCode方法来达到自己需要的需求。
    • equal方法默认是两个对象的引用的比较,意思就是指向同一内存(即进行内存地址的比较),地址则相等,否则不相等。如果你现在需要利用对象里面的值来判断是否相等,则重载equal方法。

笔者水平有限,若有错漏,欢迎指正,谢谢!


参考文章:
http://www.cnblogs.com/SharkBin/archive/2012/10/13/2722535.html
http://blog.csdn.net/jiary5201314/article/details/51439982