创建HashMap三种方式

这篇具有很好参考价值的文章主要介绍了创建HashMap三种方式。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

今天看到了HashMap的一种新的创建方式,观察其底层代码后,决定将其记录,并复习了一下HashMap的相关知识。
HashMap作为一种常用的数据结构,通常情况下我们通过前两种方法对其进行创建。今天看到了第三种创建方式。

    int capacity = 8;
    HashMap<String, String> map1 = new HashMap<>();
    HashMap<String, String> map2 = new HashMap<>(capacity);
    HashMap<String, String> map3 = Maps.newHashMapWithExpected(capacity);

new HashMap<>()

第一种map1的创建方式通常不做推荐,没有设置容量大小,在创建时会采用HashMap的默认大小16(由HashMap类中DEFAULT_INITIAL_CAPACITY 指定)。

    /**
     * The default initial capacity - MUST be a power of two.
     */
    static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16

该方法由于没有指定容量大小,实际容量小时造成空间浪费。实际容量大,则会频繁扩容,耗费时间。

new HashMap<>(capacity)

第二种map2的创建方式被经常使用,会根据实际应用场景来设置所创建的HashMap容量大小。但是观察底层代码发现,实际创建的HashMap容量大小并非所设置的值。

    /**
     * Constructs an empty <tt>HashMap</tt> with the specified initial
     * capacity and the default load factor (0.75).
     *
     * @param  initialCapacity the initial capacity.
     * @throws IllegalArgumentException if the initial capacity is negative.
     */
    public HashMap(int initialCapacity) {
        this(initialCapacity, DEFAULT_LOAD_FACTOR);
    }

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

    /**
     * Returns a power of two size for the given target capacity.
     */
    static final int tableSizeFor(int cap) {
        int n = cap - 1;
        n |= n >>> 1;
        n |= n >>> 2;
        n |= n >>> 4;
        n |= n >>> 8;
        n |= n >>> 16;
        return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
    }

可以看到,指定容量创建HashMap,代码会对参数进行相关判断,此时扩容因子为默认的0.75。然后将容量(threshold )设置成给定目标容量的两次幂。这里解释两个地方:

  • 给定目标容量的两次幂:大于等于给定值的最小的二次幂(2n)。比如:传入7,返回8(23);传入8,返回8(23);传入9,返回16(24
  • threshold:当HashMap的size大于threshold时会执行resize操作

Maps.newHashMapWithExpected(capacity)

今天看到了map3所示的HashMap创建方法。该方法由google提供的guava包所提供

		<!-- google java lib -->
		<dependency>
			<groupId>com.google.guava</groupId>
			<artifactId>guava</artifactId>
			<version>17.0</version>
		</dependency>

其底层代码如下:


//@return a new, empty {@code HashMap} with enough capacity to hold {@code expectedSize} entries without resizing
  public static <K, V> HashMap<K, V> newHashMapWithExpectedSize(int expectedSize) {
    return new HashMap<K, V>(capacity(expectedSize));
  }
 
  static int capacity(int expectedSize) {
    if (expectedSize < 3) {
      checkNonnegative(expectedSize, "expectedSize");
      return expectedSize + 1;
    }
    if (expectedSize < Ints.MAX_POWER_OF_TWO) { //MAX_POWER_OF_TWO = 1 << (Integer.SIZE - 2);
      // This is the calculation used in JDK8 to resize when a putAll
      // happens; it seems to be the most conservative(保守的) calculation we
      // can make.  0.75 is the default load factor.
      return (int) ((float) expectedSize / 0.75F + 1.0F);
    }
    return Integer.MAX_VALUE; // any large value //MAX_VALUE = 0x7fffffff;

可以看到,通过该方法创建HashMap,创建的大小是 expectedSize / 0.75F + 1.0F,和方法二最大的区别就是其对传入的容量大小进行计算,将得到的结果设置给capacity。
复习了一下HashMap的知识就可以知道这样做的好处。因为HashMap的resize操作触发时机,由容量大小和扩容因子共同决定。当HashMap的size大于threshold时进行resize操作。threshold为capacity*loadFactor,而loadFactor默认是0.75。因此,假设我们预计HashMap共有32个数据,则将其容量设置成32/0.75+1,可以使得size=32 < threshold = capacity * loadFactor = ( 32 / 0.75 + 1 ) * 0.75。在整个过程中,避免HashMap进行resize操作。文章来源地址https://www.toymoban.com/news/detail-690094.html

到了这里,关于创建HashMap三种方式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java HashMap

    Java中的HashMap是一种基于哈希表的数据结构,它可以存储键值对,其中键和值都可以是任意类型的对象。HashMap提供了快速的插入、删除和查找操作,具有高效的性能,因此在Java编程中非常常见。本文将介绍Java中的HashMap的详细信息。 哈希表的实现原理 HashMap是基于哈希表实现

    2024年02月09日
    浏览(37)
  • 详解Java HashMap

    HashMap是Map接口的实现类,基于哈希表来存储键值对。 HashMap可以存储null的key和value,可以允许多个value为null,但是只能允许一个key为null。 JDK1.8之前的HashMap底层数据结构采用 数组+链表 实现,JDK1.8之后采用 数组+链表/红黑树 实现。数组是HashMap的主体,采用拉链法(链表)解

    2024年02月08日
    浏览(44)
  • Java集合之一——HashMap(辨析)

    看到一篇讲hashmap的文章,讲的很不错,但是有一点我觉得作者没有讲清楚,这里我说一下自己的理解。 原文,先看原文: https://blog.csdn.net/woshimaxiao1/article/details/83661464 前文概述,该博客的主要内容如下: 1. 什么是哈希表(主干为数组)、什么是哈希冲突、如何解决哈希冲突

    2024年02月15日
    浏览(44)
  • [JAVA数据结构]HashMap

    目录 1.HashMap 1.1Map的常用方法 1.2HashMap的使用案例 基于哈希表的实现的Map接口。 Map底层结构 HashMap 底层结构 哈希桶 插入/删除/查找时间复杂度 O(1) 是否有序 无序 线程安全 不安全 插入/删除/查找区别 通过哈希函数计算哈希地址 比较与覆写 自定义类型需要覆写equals和 hashCod

    2024年02月12日
    浏览(63)
  • 整数替换(力扣)HashMap + 递归 JAVA

    给定一个正整数 n ,你可以做如下操作: 如果 n 是偶数,则用 n / 2替换 n 。 如果 n 是奇数,则可以用 n + 1或n - 1替换 n 。 返回 n 变为 1 所需的 最小替换次数 。 示例 1: 输入:n = 8 输出:3 解释:8 - 4 - 2 - 1 示例 2: 输入:n = 7 输出:4 解释:7 - 8 - 4 - 2 - 1 或 7 - 6 - 3 - 2 - 1 示

    2024年02月15日
    浏览(32)
  • A Guide to Java HashMap

    原文链接: A Guide to Java HashMap → https://www.baeldung.com/java-hashmap

    2024年02月09日
    浏览(39)
  • 【java数据结构】HashMap和HashSet

    目录 一.认识哈希表: 1.1什么是哈希表? 1.2哈希表的表示:  1.3常见哈希函数:  二.认识HashMap和HashSet: 2.1关于Map.Entry的说明:, 2.2Map常用方法说明: 2.3HashMap的使用案例: 2.4Set常见方法说明:  2.5HashSet使用案例: 源码: 之前的学习中,如果我们要查找一个元素,肯定是要经

    2024年03月14日
    浏览(83)
  • Java魔法解密:HashMap底层机制大揭秘

    1.1 窥探Java集合框架中的设计思想 Java集合框架是Java编程中非常重要的一部分,提供了各种数据结构和算法,使得开发者能够高效地组织和操作数据。 Java集合框架的设计思想主要包括以下几个方面 : 通用性(Generality) : Java集合框架被设计成通用的、可重用的组件。这样一

    2024年02月05日
    浏览(41)
  • Java将JSONArray转为List<HashMap>

    大家好!今天给大家分享的知识是在Java中如何将JSONArray转为ListHashMap 最近在开发过程中遇到了一个问题,就是如何将JSONArray类型转为ListHashMap,于是我找到了解决办法,话不多说,直接上代码: 此处直接转肯定是不行的,需要先得到JSONArray中的JSONObject,然后保存到map,再然

    2024年01月24日
    浏览(49)
  • 【Java 数据结构】HashMap和HashSet

    目录 1、认识 HashMap 和 HashSet 2、哈希表 2.1 什么是哈希表 2.2 哈希冲突 2.2.1 概念 2.2.2 设计合理哈希函数 - 避免冲突 2.2.3 调节负载因子 - 避免冲突 2.2.4 Java中解决哈希冲突 - 开散列/哈希桶 3、HashMap 的部分源码解读 3.1 HashMap 的构造方法 3.2 HashMap 是如何插入元素的? 3.3 哈希表

    2024年02月01日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包