HashMap、LinkedHashMap(LruCache缓存)

目录标题

  • 键值对、key-value、entry实体、散列链表
  • 注意点
    • 1,为什么HashMap的key不可以重复,value可以重复?
    • 2,HashMap的key和value是否可以为null?
    • 3,HashMap最大可以存储多少键值对?
    • 4,HashMap的查询效率
    • 5,HashMap的删除需要通过迭代器iteration ,否则容易出现异常。
    • 6,HashMap的key不可以再是一个map,但是value可以再是一个map。

键值对、key-value、entry实体、散列链表

HashMap是键值对的数据结构,存储的时候使用的是散列式存储。
java.util.HashMap的实现是一个标准的hash表+链表结构。

public class HashMap<K,V> extends AbstractMap<K,V>
    implements Map<K,V>, Cloneable, Serializable {
public abstract class AbstractMap<K, V> implements java.util.Map<K,V> {
/**
 *
 * @param  the type of keys maintained by this map
 * @param  the type of mapped values
 *
 * @author  Josh Bloch
 * @see HashMap
 * @see TreeMap
 * @see Hashtable
 * @see SortedMap
 * @see Collection
 * @see Set
 * @since 1.2
 */
public interface Map<K, V> {}

注意点

1,为什么HashMap的key不可以重复,value可以重复?

Set<K> keySet();
Collection<V> values();

可以从源码里看到,根因是HashMap的key是Set数据结构,值是Collection的。

2,HashMap的key和value是否可以为null?

HashMap对象的key、value值均可为null。

HahTable对象的key、value值均不可为null。

且两者的的key值均不能重复,若添加key相同的键值对,后面的value会自动覆盖前面的value,但不会报错。

3,HashMap最大可以存储多少键值对?

理论上是只要内存没有溢出是可以无限存储的,但是通过源码可以发现,最多存储Integer.MAX_VALUE这么多。

    /**
     * Returns the number of key-value mappings in this map.  If the
     * map contains more than {@code Integer.MAX_VALUE} elements, returns
     * {@code Integer.MAX_VALUE}.
     *
     * @return the number of key-value mappings in this map
     */
    int size();

size()方法,最大返回Integer.MAX_VALUE,当数量超过这个值依然返回这个值。

4,HashMap的查询效率

与数量无关,HashMap读取性能主要取决于放入HashMap中的key对象的hashCode方法的实现,即此方法返回值导致的Hash冲突的比例,冲突越多,性能越差。

java.util.HashMap的实现是一个标准的hash表+链表结构:

  1. HashMap中持有一个数组成员变量table
  2. table的每个元素都是一个链表(用于解决冲突)
  3. 链表的每个元素Entry都存储着一对key/value

当执行HashMap.put(key, value)的时候:

  1. HashMap会根据key.hashCode()方法来决定这一对key/value存储在数组table中的位置
  2. 若那个位置上已经有一个链表(发生冲突),则接到链表尾端,否则作为链表头存储

那么当执行HashMap.get(key)的时候,查询过程也是一样的两步:

  1. 根据key.hashCode()方法确定在table中的位置
  2. 遍历所在位置的链表,若找到equals的key则返回,否则返回null

所以key.hashCode()导致产生冲突的数量决定了这张HashMap的查询性能。

5,HashMap的删除需要通过迭代器iteration ,否则容易出现异常。

iteration 进行Map的增删改查是最安全的,因为iteration 是Map的内部类接口,避免了异步造成的数据不同步。
如果不适用迭代器进行Map的删除操作,特别是在并发情况下,很容易出现例如,一个5个元素的map,已经删除了一个元素,在取值的时候依然去取第五个元素的情况。

6,HashMap的key不可以再是一个map,但是value可以再是一个map。

链接:
Java集合的常见用法你知道多少 https://blog.csdn.net/weixin_35874254/article/details/112366244
LruCache、HashMap和LinkedHashMap的使用 https://blog.csdn.net/WLX10428/article/details/119053394

你可能感兴趣的:(知识归档,hash)