HashMap、HashTable、LinkedHashMap、TreeMap使用和区别

1.HashMap继承AbstractMap 实现Map接口,Map在java.util包中是独立的接口,不是继承Collection接口,继承Collection接口的有:

/**
* @see Set
* @see List
* @see Map
* @see SortedSet
* @see SortedMap
* @see HashSet
* @see TreeSet
* @see ArrayList
* @see LinkedList
* @see Vector
* @see Collections
* @see Arrays
* @see AbstractCollection
* @since 1.2
*/

public interface Collection<E> extends Iterable<E> {...}

实现Map接口的类有:

 * @see HashMap
* @see TreeMap
* @see Hashtable
* @see SortedMap
* @see Collection
* @see Set
* @since 1.2
*/
public interface Map<K,V> {...}




HashMap的申明方法是:
public class HashMap<K,V> extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializable {...}

HashMap是Map接口中最常用的实现类,存储Key-Vlaue键值对,HashMap不保证元素的顺序但是保证Key是唯一的

1.1 添加元素,提供了三种方法添加元素:
//单个添加元素,重复key值会覆盖
public V put(K key, V value) {
return putVal(hash(key), key, value, false, true);
}
//批量添加

public void putAll(Map<? extends K, ? extends V> m) {
    putMapEntries(m, true);
}
//单个添加,如果key存在不希望value值被覆盖
public V putIfAbsent(K key, V value) {
return putVal(hash(key), key, value, true, true);
}

1.2 删除元素:
有两个方法的重载:
public boolean remove(Object key, Object value) {
return removeNode(hash(key), key, value, true, true) != null;
}
public V remove(Object key) {
Node<K,V> e;
return (e = removeNode(hash(key), key, null, false, true)) == null ?
null : e.value;
}
1.3 修改元素
两个方法的重载:
@Override
public boolean replace(K key, V oldValue, V newValue) {
Node<K,V> e; V v;
if ((e = getNode(hash(key), key)) != null &&
((v = e.value) == oldValue || (v != null && v.equals(oldValue)))) {
e.value = newValue;
afterNodeAccess(e);
return true;
}
return false;
}

@Override
public V replace(K key, V value) {
Node<K,V> e;
if ((e = getNode(hash(key), key)) != null) {
V oldValue = e.value;
e.value = value;
afterNodeAccess(e);
return oldValue;
}
return null;
}

1.4 判断集合是否为空:
public boolean isEmpty() {
return size == 0;
}

1.5 判断集合元素大小:
public int size() {
return size;
}

1.6 遍历元素
a,使用keySet获取所有的key,然后遍历
b,使用Map.entrySet获取所有的元素,然后使用iterator遍历,返回的是一个set集合,Set<Map.Entry<K,V>>
c,使用Map.entrySet获取所有的元素,然后使用foreach循环遍历
d,直接使用values获取所有的值,然后遍历,这种方式获取不到key

1.7 清空集合

/**
* Removes all of the mappings from this map.
* The map will be empty after this call returns.
*/
public void clear() {
Node<K,V>[] tab;
modCount++;
if ((tab = table) != null && size > 0) {
size = 0;
for (int i = 0; i < tab.length; ++i)
tab[i] = null;
}
}


2.HashTable也是Map的实现类,它的方法是同步的,所以是线程安全的
HashTable的申明方法:
public class Hashtable<K,V>
extends Dictionary<K,V>
implements Map<K,V>, Cloneable, java.io.Serializable {...}
HashTable继承的是Dictionary,HashMap继承的是AbstractMap

HashTable的方法都是同步的,使用方法基本和HashMap是一致的
public synchronized V put(K key, V value) {
public synchronized boolean isEmpty() {
return count == 0;
}

3.LinkedHashMap也是实现了Map接口
public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V>

从申明中可以看出,LinkedHashMap继承了HashMap类,不同的地方在于使用了链表,因此可以保证元素的插入顺序,先进先出


4.TreeMap也是Map的实现类,它继承了AbstractMap
申明方法如下:
public class TreeMap<K,V>
extends AbstractMap<K,V>
implements NavigableMap<K,V>, Cloneable, java.io.Serializable

TreeMap中的元素也是有序的,默认的排序规则是按照key的字段顺序升序排序的


总结一下:
这四个都是Map接口的实现类
保证key是唯一的,不可重复

HashMap、HashTable不保证元素的顺序
LinkedHashMap是有序的,按照插入顺序,先进先出
TreeMap是保证元素顺序的,默认按照字典排序升序,支持自定义排序规则

HashMap支持key和value都是null,LinkedHashMap继承HashMap所以也是支持的
TreeMap不允许key是null,但是允许value是null
HashTable不允许null值,key和value都不允许


HashMap、LinkedHashMap、TreeMap都不是线程安全的,HashTable是线程安全的

HashTable的父类是Dictionary,HashMap、LinkedHashMap、TreeMap的父类AbstracMap

上一篇:TreeMap简介


下一篇:JAVA集合之二—TreeMap