HashMap

说明

Map 接口的基于哈希表的实现。此实现提供了所有可选的映射操作,并允许 null 值和 null 键。 (HashMap 类大致等同于 Hashtable,除了它是非同步的并且允许空值。)该类不保证映射的顺序;特别是,它不保证订单会随着时间的推移保持不变。

此实现为基本操作(get 和 put)提供恒定时间性能,假设散列函数将元素正确地分散到存储桶中。集合视图上的迭代需要的时间与 HashMap 实例的“容量”(桶的数量)加上它的大小(键值映射的数量)成正比。因此,如果迭代性能很重要,则不要将初始容量设置得太高(或负载因子太低),这一点非常重要。

HashMap 的实例有两个影响其性能的参数:initial capacityload factor容量是哈希表中的桶数,初始容量只是哈希表创建时的容量。 负载因子 是衡量哈希表在其容量自动增加之前允许达到多满的指标。当哈希表中的条目数超过负载因子和当前容量的乘积时,对哈希表进行重新哈希(即重新构建内部数据结构),这样哈希表大约有两倍桶的数量。

作为一般规则,默认负载因子 (0.75) 在时间和空间成本之间提供了很好的权衡。较高的值会减少空间开销,但会增加查找成本(反映在 HashMap 类的大多数操作中,包括 get 和 put)。在设置其初始容量时,应考虑映射中的预期条目数及其负载因子,以尽量减少重新哈希操作的次数。如果初始容量大于最大条目数除以负载因子,则不会发生重新哈希操作。

如果许多映射要存储在一个 HashMap 实例中,创建一个足够大的容量将允许映射更有效地存储,而不是让它根据需要执行自动重新散列来增加表。请注意,使用具有相同 hashCode() 的多个键是降低任何哈希表性能的可靠方法。为了改善影响,当键是 Comparable 时,此类可以使用键之间的比较顺序来帮助打破联系。

注意这个实现不是同步的。如果多个线程同时访问一个哈希映射,并且至少有一个线程在结构上修改了映射,它必须在外部同步。 (结构修改是添加或删除一个或多个映射的任何操作;仅更改与实例已包含的键关联的值不是结构修改。)这通常是通过同步一些自然封装映射的对象来完成的.如果不存在此类对象,则应使用 CollectionssynchronizedMap Collections.synchronizedMap 方法“包装”地图。这最好在创建时完成,以防止对地图的意外不同步访问: Map m = Collections.synchronizedMap(new HashMap(...));

所有此类返回的迭代器“集合视图方法”是fail-fast:如果在迭代器创建后的任何时间以任何方式修改地图结构,除了通过迭代器自己的remove 方法,迭代器将抛出一个 ConcurrentModificationException。因此,面对并发修改,迭代器快速而干净地失败,而不是在未来不确定的时间冒着任意、非确定性行为的风险。

请注意,无法保证迭代器的快速失败行为,因为一般来说,在存在非同步并发修改的情况下不可能做出任何硬性保证。快速失败的迭代器会尽最大努力抛出 ConcurrentModificationException。因此,编写一个依赖此异常来确保其正确性的程序是错误的:迭代器的快速失败行为应该仅用于检测错误。

源码说明(仅部分代码)

 /**
     * 默认的初始容量,必须是2的幂指数
     */
    static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16

    /**
     * 最大容量,在两个带参数的构造函数隐式指定更高值时使用。必须是 2 的幂 <= 1<<30。
     */
    static final int MAXIMUM_CAPACITY = 1 << 30;

    /**
     * 默认的负载因子,大小为0.75
     */
    static final float DEFAULT_LOAD_FACTOR = 0.75f;

    /**
     * 使用树而不是列表的 bin 计数阈值。将元素添加到至少具有这么多节点的 bin 时,bin 会转换为树。该值必须大于 2 且至少应为 8,以与树移除中关于在收缩时转换回普通 bin 的假设相匹配。(就是小于8的时候,采用链表,大于等于8时采用树结构)
     */
    static final int TREEIFY_THRESHOLD = 8;

    /**
     * 在调整大小操作期间取消(拆分)bin 的 bin 计数阈值。应小于 TREEIFY_THRESHOLD,最多为 6 以在移除下进行收缩检测。
     */
    static final int UNTREEIFY_THRESHOLD = 6;

    /**
     * 可以将 bin 树化的最小表容量。 (否则,如果 bin 中的节点过多,则表将调整大小。)应至少为 4 TREEIFY_THRESHOLD,以避免调整大小和树化阈值之间发生冲突。
     */
    static final int MIN_TREEIFY_CAPACITY = 64;

    /**
     * 节点说明,hash值和key值是final修饰的
     */
    static class Node<K,V> implements Map.Entry<K,V> {
   
        final int hash;
        final K key;
        V value;
        Node<K,<
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值