热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

HashMap源码解析一、构造函数,华为软件开发面试题

this(initialCapacity,DEFAULT_LOAD_FACTOR);}**paraminitialCapacity初始容量paramloadFactor负载因子

this(initialCapacity, DEFAULT_LOAD_FACTOR);
}

/**

  • @param initialCapacity 初始容量
  • @param loadFactor 负载因子
    */
    public HashMap(int initialCapacity, float loadFactor) {
    if (initialCapacity <0)
    throw new IllegalArgumentException("Illegal initial capacity: " &#43;
    initialCapacity);
    if (initialCapacity > MAXIMUM_CAPACITY)
    initialCapacity &#61; MAXIMUM_CAPACITY;
    if (loadFactor <&#61; 0 || Float.isNaN(loadFactor))
    throw new IllegalArgumentException("Illegal load factor: " &#43;
    loadFactor);
    this.loadFactor &#61; loadFactor;
    this.threshold &#61; tableSizeFor(initialCapacity);
    }

public HashMap(Map m) {
this.loadFactor &#61; DEFAULT_LOAD_FACTOR;
putMapEntries(m, false);
}
}

HashMap(int initialCapacity, float loadFactor) 构造函数

前两个没什么好讲的&#xff0c;我们直接看第3个 HashMap(int initialCapacity, float loadFactor)
这里的重点就是 int tableSizeFor(int cap)函数。

tableSizeFor(int cap) 函数

tableSizeFor(int cap) 的作用是返回 大于等于cap 且 最接近cap 的2的幂次方的值

static final int MAXIMUM_CAPACITY &#61; 1 <<30;
/**

  • Returns a power of two size for the given target capacity.
  • 返回 大于等于cap 且 最接近cap 的2的幂次方的值
    */
    static final int tableSizeFor(int cap) {
    int n &#61; cap - 1;
    n |&#61; n >>> 1;
    n |&#61; n >>> 2;
    n |&#61; n >>> 4;
    n |&#61; n >>> 8;
    n |&#61; n >>> 16;
    return (n <0) ? 1 : (n >&#61; MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n &#43; 1;
    }

我们分步骤解析
一下这个函数&#xff1a;

  1. >>> 无符号右移运算符&#xff0c;高位用0 填充。如下&#xff1a;

a &#61; 1010
a >>> 1 &#61; 0101

  1. | 如果相对应位都是 0&#xff0c;则结果为 0&#xff0c;否则为 1。如下&#xff1a;

a &#61; 1010
b &#61; 0011

a | b &#61; 1011

  1. |&#61; , a |&#61; b 等同于 a &#61; a|b

这时候我们就能看懂 n |&#61; n >>> 1; 等同于 n &#61; n | n >>> 1

  1. int n &#61; cap - 1; 是因为如果cap不减1&#xff0c;当 cap 本来就是2次幂数值&#xff0c;就会导致返回的结果为 cap*2 。

  2. 我们带入一个值看下运行结果&#xff0c;假设 cap &#61; 20

static final int tableSizeFor(int cap) {
System.out.println("cap &#61; "&#43; Integer.toBinaryString(cap));
int n &#61; cap - 1;
System.out.println("n &#61; "&#43; Integer.toBinaryString(n));
n |&#61; n >>> 1;
System.out.println("n1 &#61; "&#43; Integer.toBinaryString(n));
n |&#61; n >>> 2;
System.out.println("n2 &#61; "&#43; Integer.toBinaryString(n));
n |&#61; n >>> 4;
System.out.println("n4 &#61; "&#43; Integer.toBinaryString(n));
n |&#61; n >>> 8;
System.out.println("n8 &#61; "&#43; Integer.toBinaryString(n));
n |&#61; n >>> 16;
System.out.println("n16 &#61; "&#43; Integer.toBinaryString(n));
System.out.println("n&#43;1 &#61; "&#43; Integer.toBinaryString(n&#43;1));
return (n <0) ? 1 : (n >&#61; MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n &#43; 1;
}

&#64;Test
public void tableSizeForTest(){
System.out.println(“tableSizeFor:”&#43; tableSizeFor(20));
}

我这里直接把tableSizeFor(int cap) 拷贝出来&#xff0c;然后添加了日志。结果如下&#xff1a;

cap &#61; 10100
n &#61; 10011
n1 &#61; 11011 (10011 | 01001)
n2 &#61; 11111 (11011 | 01101)
cap) 拷贝出来&#xff0c;然后添加了日志。结果如下&#xff1a;

cap &#61; 10100
n &#61; 10011
n1 &#61; 11011 (10011 | 01001)
n2 &#61; 11111 (11011 | 01101)


推荐阅读
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • 如何自行分析定位SAP BSP错误
    The“BSPtag”Imentionedintheblogtitlemeansforexamplethetagchtmlb:configCelleratorbelowwhichi ... [详细]
  • Spring源码解密之默认标签的解析方式分析
    本文分析了Spring源码解密中默认标签的解析方式。通过对命名空间的判断,区分默认命名空间和自定义命名空间,并采用不同的解析方式。其中,bean标签的解析最为复杂和重要。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • JavaSE笔试题-接口、抽象类、多态等问题解答
    本文解答了JavaSE笔试题中关于接口、抽象类、多态等问题。包括Math类的取整数方法、接口是否可继承、抽象类是否可实现接口、抽象类是否可继承具体类、抽象类中是否可以有静态main方法等问题。同时介绍了面向对象的特征,以及Java中实现多态的机制。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • Android JSON基础,音视频开发进阶指南目录
    Array里面的对象数据是有序的,json字符串最外层是方括号的,方括号:[]解析jsonArray代码try{json字符串最外层是 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • Go Cobra命令行工具入门教程
    本文介绍了Go语言实现的命令行工具Cobra的基本概念、安装方法和入门实践。Cobra被广泛应用于各种项目中,如Kubernetes、Hugo和Github CLI等。通过使用Cobra,我们可以快速创建命令行工具,适用于写测试脚本和各种服务的Admin CLI。文章还通过一个简单的demo演示了Cobra的使用方法。 ... [详细]
  • 开发笔记:实验7的文件读写操作
    本文介绍了使用C++的ofstream和ifstream类进行文件读写操作的方法,包括创建文件、写入文件和读取文件的过程。同时还介绍了如何判断文件是否成功打开和关闭文件的方法。通过本文的学习,读者可以了解如何在C++中进行文件读写操作。 ... [详细]
  • 本文介绍了深入浅出Linux设备驱动编程的重要性,以及两种加载和删除Linux内核模块的方法。通过一个内核模块的例子,展示了模块的编译和加载过程,并讨论了模块对内核大小的控制。深入理解Linux设备驱动编程对于开发者来说非常重要。 ... [详细]
  • SpringBoot uri统一权限管理的实现方法及步骤详解
    本文详细介绍了SpringBoot中实现uri统一权限管理的方法,包括表结构定义、自动统计URI并自动删除脏数据、程序启动加载等步骤。通过该方法可以提高系统的安全性,实现对系统任意接口的权限拦截验证。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
author-avatar
L爱你j_828
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有