Map 系列 —— HashMap(JDK1.8)

Map 系列 —— HashMap(JDK1.8)

1. Map 接口概述

本文源码基于 JDK1.8

Map 接口定义: 将 key 映射到 value 的一个对象。Map 不能包含重复的 key,每个 key 最多映射一个 value。

Map 接口提供了三个集合视图,来表达 Map 的内容

  • key 值的 set 集合
  • value 值的 collection 集合
  • key-value 映射的 set 集合,这个其实就是 Set<Map.Entry<K, V>>

至于 map 的顺序问题是由 map 集合视图上的迭代器返回其元素的顺序决定的。但是有一些 map 的实现可以保证排序问题,例如 TreeMap

注意如果将可变对象作为 map 的 key 则必须非常小心。

所有通用 map 实现类都应该提供两个“标准”构造函数:

  • 一个无参数的构造函数,创建一个 empty map
  • 一个类型为 Map 参数的构造函数,创建一个具有相同键值的新 map

2. HashMap 概述

基于哈希表的 Map 接口实现。此实现提供所有可选的 map 操作,并允许 null valuesnull key。 (HashMap 大致相当于 Hashtable,除了 HashMap 是不同步的并且允许空值)。HashMap 不保证有序,也不保证顺序不随时间变化。

假设散列函数在 buckets 之间正确的分散元素,那么 HashMap 为基本操作(get 和 put)提供了恒定时间性能

HashMap 有两个影响其性能的参数:初始容量(initial capacity)和负载因子(load factor)。容量就是哈希表中 buckets 的数量,负载因子就是 buckets 填满程度的最大比例。当 buckets 填充的数目大于 capacity * load factor 时,就需要调整 buckets 的数目为当前的 2 倍。
如果对迭代性能要求很高的话不要把 initial capacity 设置过大,也不要把 load factor 设置太小。HashMap 开头的注释是这样描述的

Thus, it’s very important not to set the initial capacity too high (or the load factor too low) if iteration performance is important.

3. 几个常量

// 默认的 initial capacity —— 必须是 2 的幂
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16

// 最大的 capacity
static final int MAXIMUM_CAPACITY = 1 << 30;

// 默认的加载因子
static final float DEFAULT_LOAD_FACTOR = 0.75f;

// 使用 tree 而不是 list 的阈值
static final int TREEIFY_THRESHOLD = 8;

/**
* The bin count threshold for untreeifying a (split) bin during a
* resize operation. Should be less than TREEIFY_THRESHOLD, and at
* most 6 to mesh with shrinkage detection under removal.
*/
static final int UNTREEIFY_THRESHOLD = 6;

/**
* The smallest table capacity for which bins may be treeified.
* (Otherwise the table is resized if too many nodes in a bin.)
* Should be at least 4 * TREEIFY_THRESHOLD to avoid conflicts
* between resizing and treeification thresholds.
*/
static final int MIN_TREEIFY_CAPACITY = 64;

4. Node 节点

	// 基本的 hash bin node,用于大多数 entries
	static class Node<K,V> implements Map.Entry<K,V> {
   
        final int hash;
        final K key;
        V value;
        Node<K,V> next;

HashMap 结构

5. 相关实现

5.1 构造函数

HashMap 一共有四个构造函数:

    /**
     * Constructs an empty <tt>HashMap</tt> with the default initial capacity
     * (16) and the default load factor (0.75).
     */
    public HashMap() {
   
        this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted
    }

    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);
    }

    public HashMap(
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值