Bootstrap

常见Java容器对比

线索:

1. 对比HashMap、HashTable、TreeMap、LinkedHashMap

2. 对比HashSet、TreeSet、LinkedHashSet

3. Map的四种遍历方式

4. 散列表的应用:word拼错错误功能

 

1. 对比HashMap、HashTable、TreeMap、LinkedHashMap

都是Map的实现,以“键值对”形式存取。

 

HashTable是线程安全的,但里边都是类似public synchronized V get(Object key) 的实现,不支持高并发,如果有线程安全的需求,可以使用ConcurrentHashMap

 

HashMap是线程不安全,是大多数场景的首选。散列表的put、get的时间复杂度是O(1)

 

TreeMap底层基于红黑树,因此get、put、remove之类的操作的时间复杂度是O(logN)。TreeMap是一种有序集合,具体顺序可以由指定的 Comparator 来决定,或者根据键的自然顺序来判断// Comparable。

 

LinkedHashMap是HashMap的子类,它也保证某种顺序,即遍历顺序按 插入顺序 或 访问顺序。其中,put、get、compute 等,都算“访问”。此外,使用LinkedHashMap可以轻松实现LRU缓存淘汰算法。比如,我们构建一个空间占用敏感的资源池,希望可以自动将最近不常被访问(LRU)的对象释放掉,这就可以利用 LinkedHashMap 提供的机制来实现。

 

2. 对比HashSet、TreeSet、LinkedHashSet

Set不允许重复元素。所谓的不重复、唯一性,指的是不存在两个对象equals返回true,不重复也是Set和List最明显的差别。在需要保证元素唯一性的场景下,可以使用Set集合。

 

HashSet是HashMap的马甲;TreeSet是TreeMap的马甲;LinkedHashSet是LinkedHashMap的马甲。因此讨论Set类的性能,实际上是谈论Map类的性能。

以HashSet为例:

// Dummy value to associate with an Object in the backing Map
private static final Object PRESENT = new Object();

/**
 * Adds the specified element to this set if it is not already present.
 * More formally, adds the specified element {@code e} to this set if
 * the set contains no element {@code e2} such that
 * {@code Objects.equals(e, e2)}.
 * If this set already contains the element, the call leaves the set
 * unchanged and returns {@code false}.
public boolean add(E e) {
    return m.put(e, PRESENT)==null; // 这里的m其实就是HashMap或TreeMap
}

3. Map的四种遍历方式:entrySet()、iterator、keySet()、values()

values返回的是v的集合: Collection values(); 主要用以单遍历value,而不要key

Iterator> iterator = hashMap.entrySet().iterator();
while (iterator.hasNext()) {
  Map.Entry entry = iterator.next();
  System.out.println(entry.getKey() + ":" + entry.getValue());
}

4. word拼错错误功能,散列表的应用。

使用word时,假设你有一个单词拼错了,比如appla,word会以红色波浪线的形式提醒你“拼写错误”。这个功能的实现就用到了散列表。

常用的英文单词有20万个左右,假设单词的平均长度是 10 个字母,平均一个单词占用 10 个字节的内存空间,那 20 万英文单词大约占 2MB 的存储空间,就算放大 10 倍也就 20MB。完全可以放到内存里。

我们用散列表来存储整个英文单词词典,当用户输入某个英文单词时,我们拿着用户输入的单词到散列表中查找,如果找到则拼写正确;反之,则可能拼写有误。