天天看点

Java基础之集合(二)1.2 Map

目录

1.2 Map

1.2.1HashMap

1.2.2ConcurrentHashMap

 1.2.3 HashTable

1.2.4TreeMap

1.2.5LinkedHashMap

1.2 Map

Map提供了一个更通用的元素存储方法,用于存储元素对(Key-Value),每个键映射一个值。

1.2.1HashMap

HashMap基于键的HashCode值唯一标识一条数据,同时基于键的HashCode值进行数据的存取,因此可以快速地更新和查询数据,但每次遍历的顺序无法保证相同。HashMap的Key和Value允许为空。

底层由数组+链表+红黑树组成

Java基础之集合(二)1.2 Map
public HashMap(int initialCapacity, float loadFactor) {
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal initial capacity: " +
                                               initialCapacity);
        if (initialCapacity > MAXIMUM_CAPACITY)
            initialCapacity = MAXIMUM_CAPACITY;
        if (loadFactor <= 0 || Float.isNaN(loadFactor))
            throw new IllegalArgumentException("Illegal load factor: " +
                                               loadFactor);
        this.loadFactor = loadFactor;
        this.threshold = tableSizeFor(initialCapacity);
    }
           
  •  initialCapacity:当前数组的容量,默认为16,可以扩容,扩容后数组的大小为当前的2倍,值始终为
    Java基础之集合(二)1.2 Map
  • loadFactor:负载因子,默认为0.75.
static class Node<K,V> implements Map.Entry<K,V> {
        final int hash;
        final K key;
        V value;
        Node<K,V> next;

        Node(int hash, K key, V value, Node<K,V> next) {
            this.hash = hash;
            this.key = key;
            this.value = value;
            this.next = next;
        }
           
Java基础之集合(二)1.2 Map

 数组中每个Entry实例都是一个链表或红黑树,默认数组中的Entry实例为链表,当链表中元素个数超过8个,HashMap会将链表结构转换成红黑树结构以提高查询效率。

HashMap在查找数据时,首先根据哈希值快速定位到数组的具体下标,在定位到数组下标后,如果Entry实例为链表,对链表进行顺序遍历,时间复杂度为O(n),若Entry实例为红黑树,查找的复杂度为O(logN),效率得到了大大的提升。

HashMap非线程安全,若需要满足线程安全,可以使用sychronizedMap()使HashMap具有线程安全的能力,或者使用ConcurrentHashMap代替HashMap。

1.2.2ConcurrentHashMap

在Java7中ConcurrentHashMap采用分段锁的实现并发操作,因此他是线程安全的。ConcurrentHashMap由多个Segment组成,每次加锁锁住的都是一个Segment,当保证了每个Segment都是线程安全的就保证了全局都是线程安全的。ConcurrentHashMap默认由16个Segment组成,在这种情况下,最多支持16个线程执行写操作。

Java基础之集合(二)1.2 Map

 在Java8中,CurrentHashMap弃用了Segment分段锁,改用了Synchronized+CAS实现对多线程的安全操作,数据结构同HashMap一致

Java基础之集合(二)1.2 Map

 1.2.3 HashTable

HashTable很多功能与HashMap类似,不同的是,它是线程安全的,与ConcurrentHashMap不同的是,他同一时刻只能拥有一个线程写HashTable,并发性远远不如ConcurrentHashMap。他的一些方法都被Synchronized修饰。

1.2.4TreeMap

TreeMap是基于二叉树数据结构存储数据

static final class Entry<K,V> implements Map.Entry<K,V> {
        K key;
        V value;
        Entry<K,V> left;
        Entry<K,V> right;
        Entry<K,V> parent;
        boolean color = BLACK;

        /**
         * Make a new cell with given key, value, and parent, and with
         * {@code null} child links, and BLACK color.
         */
        Entry(K key, V value, Entry<K,V> parent) {
            this.key = key;
            this.value = value;
            this.parent = parent;
        }
}
           
public TreeMap() {
        comparator = null;
    }

    /**
     * Constructs a new, empty tree map, ordered according to the given
     * comparator.  All keys inserted into the map must be <em>mutually
     * comparable</em> by the given comparator: {@code comparator.compare(k1,
     * k2)} must not throw a {@code ClassCastException} for any keys
     * {@code k1} and {@code k2} in the map.  If the user attempts to put
     * a key into the map that violates this constraint, the {@code put(Object
     * key, Object value)} call will throw a
     * {@code ClassCastException}.
     *
     * @param comparator the comparator that will be used to order this map.
     *        If {@code null}, the {@linkplain Comparable natural
     *        ordering} of the keys will be used.
     */
    public TreeMap(Comparator<? super K> comparator) {
        this.comparator = comparator;
    }

    /**
     * Constructs a new tree map containing the same mappings as the given
     * map, ordered according to the <em>natural ordering</em> of its keys.
     * All keys inserted into the new map must implement the {@link
     * Comparable} interface.  Furthermore, all such keys must be
     * <em>mutually comparable</em>: {@code k1.compareTo(k2)} must not throw
     * a {@code ClassCastException} for any keys {@code k1} and
     * {@code k2} in the map.  This method runs in n*log(n) time.
     *
     * @param  m the map whose mappings are to be placed in this map
     * @throws ClassCastException if the keys in m are not {@link Comparable},
     *         or are not mutually comparable
     * @throws NullPointerException if the specified map is null
     */
    public TreeMap(Map<? extends K, ? extends V> m) {
        comparator = null;
        putAll(m);
    }

    /**
     * Constructs a new tree map containing the same mappings and
     * using the same ordering as the specified sorted map.  This
     * method runs in linear time.
     *
     * @param  m the sorted map whose mappings are to be placed in this map,
     *         and whose comparator is to be used to sort this map
     * @throws NullPointerException if the specified map is null
     */
    public TreeMap(SortedMap<K, ? extends V> m) {
        comparator = m.comparator();
        try {
            buildFromSorted(m.size(), m.entrySet().iterator(), null, null);
        } catch (java.io.IOException cannotHappen) {
        } catch (ClassNotFoundException cannotHappen) {
        }
    }
           

同时TreeMap实现了SortedMap接口,保障了元素的顺序存储。

public class TreeMap<K,V>
    extends AbstractMap<K,V>
    implements NavigableMap<K,V>, Cloneable, java.io.Serializable{}

public interface NavigableMap<K,V> extends SortedMap<K,V>{}
           

所以TreeMap常用于实现排序的映射列表,当我们使用TreeMap是,Key必须实现Comparable接口或采用自定义的比较器,否则将会抛出ClassCastException。

1.2.5LinkedHashMap

LinkedHashMap为HashMap的子类,其内部采用链表保存元素的插入顺序,当通过Iterator遍历时,采用元素的插入顺序访问元素。

public class LinkedHashMap<K,V>
    extends HashMap<K,V>
    implements Map<K,V>{}