hashmap

HashMap

元气小坏坏 提交于 2020-02-20 05:10:17
https://www.cnblogs.com/aobing/p/12014271.html HashMap是我们非常常用的数据结构,由 数组和链表组合构成 大概如下,数组里面每个地方都存了Key-Value这样的实例,在Java7叫Entry在Java8中叫Node。 因为他本身所有的位置都为null,在put插入的时候会根据key的hash去计算一个index值。 你提到了还有链表,为啥需要链表,链表又是怎么样子的呢? 我们都知道数组长度是有限的,在有限的长度里面我们使用哈希,哈希本身就存在概率性,就是”帅丙“和”丙帅“我们都去hash有一定的概率会一样,就像上面的情况我再次哈希”丙帅“极端情况也会hash到一个值上,那就形成了链表。 每一个节点都会保存自身的hash、key、value、以及下个节点,我看看Node的源码。 来源: https://www.cnblogs.com/ywsheng/p/12016418.html

阿里Java开发手册建议创建HashMap时设置初始化容量,但多少合适

做~自己de王妃 提交于 2020-02-20 04:51:48
集合是Java开发日常开发中经常会使用到的,而作为一种典型的K-V结构的数据结构,HashMap对于Java开发者一定不陌生。 关于HashMap,很多人都对他有一些基本的了解,比如他和hashtable之间的区别、他和concurrentHashMap之间的区别等。这些都是比较常见的,关于HashMap的一些知识点和面试题,想来大家一定了熟于心了,并且在开发中也能有效的应用上。 但是,作者在很多次 CodeReview 以及面试中发现,有一个比较关键的小细节经常被忽视,那就是HashMap创建的时候,要不要指定容量?如果要指定的话,多少是合适的?为什么? 要设置HashMap的初始化容量 在《HashMap中傻傻分不清楚的那些概念》中我们曾经有过以下结论: HashMap有扩容机制,就是当达到扩容条件时会进行扩容。HashMap的扩容条件就是当HashMap中的元素个数(size)超过临界值(threshold)时就会自动扩容。在HashMap中,threshold = loadFactor * capacity。 所以,如果我们没有设置初始容量大小,随着元素的不断增加,HashMap会发生多次扩容,而HashMap中的扩容机制决定了每次扩容都需要重建hash表,是非常影响性能的。 所以,首先可以明确的是,我们建议开发者在创建HashMap的时候指定初始化容量。并且

软工实践寒假作业(2/2)

邮差的信 提交于 2020-02-19 20:17:00
这个作业属于哪个课程 2020软工|S班 这个作业要求在哪里 软工实践寒假作业(2/2) 这个作业的目标 设计、开发一个疫情统计的程序、学习对程序的优化、学习GitHub的使用、PSP(个人软件开发流程)的学习使用、《构建之法》的学习 作业正文 作业正文 其他参考文献 CSDN 1.github仓库地址 我的github仓库地址 2.PSP表格 PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟) Planning 计划 40 45 Estimate 估计这个任务需要多少时间 5 5 Development 开发 200 180 Analysis 需求分析 (包括学习新技术) 160 120 Design Spec 生成设计文档 80 55 Design Review 设计复审 30 35 Coding Standard 代码规范 (为目前的开发制定合适的规范) 150 150 Design 具体设计 20 20 Coding 具体编码 200 300 Code Review 代码复审 60 70 Test 测试(自我测试,修改代码,提交修改) 340 270 Reporting 报告 150 100 Test Repor 测试报告 20 20 Size Measurement 计算工作量 45 30

HashMap知识初探

只谈情不闲聊 提交于 2020-02-19 17:53:52
public class TestHashMap { /** * HashMap是数组和链表组合构成的数据结构 * 数组里面每个地方都存了key-value这样的实例Java7叫Entry,Java8叫Node * 因为本身所有的位置都为null,在put插入的时候会根据key的hash去计算一个index值。 * 为什么需要链表? * 我们都知道数组长度是有限的,在有限的长度里面我们使用哈希,哈希本身就存在概率性,就是"12"和"21"我们都去hash有一定的概率会一样,如下面情况"12"和"21"hash到一个值上,那就形成了链表。 * * 数组容量是有限的,数据多次插入,到达一定的数量就会进行扩容,也就是resize * 扩容条件:Capacity:HashMap当前长度;LoadFactor:负载因子,默认值0.75f * 扩容分2步:1、扩容:创建一个Entry的空数组,长度是原数组的2倍 2、ReHash:遍历原Entry数组,把所有的Entry重新Hash到新数组 * * 为什么要重新Hash,直接复制过去不好吗? * 因为长度扩大以后,Hash的规则也随之改变 * Hash的公式---> index = HashCode(Key) & (Length - 1) * 原来长度(Length)是8你位运算出来的值是4 ,新的长度是16你位运算出来的值明显不一样了。 *

java面试题 -- 基础

醉酒当歌 提交于 2020-02-19 15:12:30
1.抽象和封装的不同点 抽象和封装是互补的概念。一方面,抽象关注对象的行为。另一方面,封装关注对象行为的细节。一般是通过隐藏对象内部状态信息做到封装,因此,封装可以看成是用来提供抽象的一种策略。 2.重载和重写的区别 重载: 发生在同一个类中,方法名必须相同,参数类型不同、个数不同、顺序不同,方法返回值和访问修饰符可以不同,发生在编译时。 重写: 发生在父子类中,方法名、参数列表必须相同,返回值范围小于等于父类,抛出的异常范围小于等于父类,访问修饰符范围大于等于父类;如果父类方法访问修饰符为private则子类就不能重写该方法。 3.字符型常量和字符串常量的区别 字符常量是单引号引起的一个字符 字符串常量是双引号引起的若干个字符字符常量相当于一个整形值(ASCII值),可以参加表达式运算 字符串常量代表一个地址值(该字符串在内存中存放位置)字符常量只占一个字节 字符串常量占若干个字节(至少一个字符结束标志)4.成员变量与局部变量的区别有那些? 从语法形式上,看成员变量是属于类的,而局部变量是在方法中定义的变量或是方法的参数;成员变量可以被public,private,static等修饰符所修饰,而局部变量不能被访问控制修饰符及static所修饰;但是,成员变量和局部变量都能被final所修饰;从变量在内存中的存储方式来看,成员变量是对象的一部分,而对象存在于堆内存

Scala—— 18.映射Map

左心房为你撑大大i 提交于 2020-02-19 02:22:17
Scala中的Map和Java类似,也是一个散列表,它存储的内容也是键值对(key-value)映射,Scala中不可变的Map是有序的,可变的Map是无序的。 Scala中,有可变Map(scala.collection.mutable.Map)和不可变Map(scala.collection.immutable.Map)。 Scala中的不可变Map是有序的。 1.构造不可变映射 默认Map是 immutable.Map,key-value 类型支持Any,在Map的底层,每对key-value是Tuple2, 输出的结果中,输出顺序和声明顺序一致 。 scala > val map1 = Map ( "Alice" - > 19, "Tom" - > 20, "Jack" - > 21 ) map1: scala.collection.immutable.Map [ String,Int ] = Map ( Alice - > 19, Tom - > 20, Jack - > 21 ) scala > print ( map1 ) Map ( Alice - > 19, Tom - > 20, Jack - > 21 ) 2.构造可变映射 scala > val map2 = scala.collection.mutable.Map ( "Alice" - > 19,

Map源码会问哪些面试题

爷,独闯天下 提交于 2020-02-18 15:20:34
1 Map 整体数据结构类问题 1.1 说一说 HashMap 底层数据结构 答:HashMap 底层是数组 + 链表 + 红黑树的数据结构,数组的主要作用是方便快速查找,时间复杂度是 O(1),默认大小是 16,数组的下标索引是通过 key 的 hashcode 计算出来的,数组元素叫做 Node,当多个 key 的 hashcode 一致,但 key 值不同时,单个 Node 就会转化成链表,链表的查询复杂度是 O(n),当链表的长度大于等于 8 并且数组的大小超过 64 时,链表就会转化成红黑树,红黑树的查询复杂度是 O(log(n)),简单来说,最坏的查询次数相当于红黑树的最大深度。 1.2 HashMap、TreeMap、LinkedHashMap 三者有啥相同点,有啥不同点? 答:相同点: 三者在特定的情况下,都会使用红黑树; 底层的 hash 算法相同; 在迭代的过程中,如果 Map 的数据结构被改动,都会报 ConcurrentModificationException 的错误。 不同点: HashMap 数据结构以数组为主,查询非常快,TreeMap 数据结构以红黑树为主,利用了红黑树左小右大的特点,可以实现 key 的排序,LinkedHashMap 在 HashMap 的基础上增加了链表的结构,实现了插入顺序访问和最少访问删除两种策略; 由于三种 Map

深入理解JDK8 HashMap

岁酱吖の 提交于 2020-02-18 08:36:18
笔者在上一篇文章《 深入理解JDK7 HashMap 》中详细解析了HashMap在JDK7中的实现原理,主要是围绕其put、get、resize、transfer等方法,本文将继续解析HashMap在JDK8中的具体实现,首先也将从put、get、resize等方法出发,着重解析HashMap在JDK7和JDK8中的具体区别,最后回答并解析一些常见的HashMap问题。在阅读本篇文章之前,建议阅读上一篇文章作为基础。 一、HashMap在JDK8中的结构 上一篇文章提到,HashMap在JDK7或者JDK8中采用的基本存储结构都是 数组+链表 形式,可能有人会提出疑问,HashMap在JDK8中不是 数组+链表+红黑树 吗?本文的回答 是 。至于为什么JDK8在一定条件下将链表转换为红黑树,我相信很多人都会回答: 为了提高查询效率 。基本答案可以说是这样的,JDK7中的HashMap对着Entry节点增多,哈希碰撞的概率在慢慢变大,这就直接导致哈希表中的单链表越来越长,这就大大降低了HashMap的查询能力,且时间复杂度可能会退化到O(n)。针对这种情况,JDK8做出了优化,就是在一定的条件下,链表会被转换为红黑树,提升查询效率。 HashMap在JDK8中基本结构示意图如下所示: 在上面的示意图可以看出,与JDK7的最大区别就是哈希表中不仅有链表,还有可能存在红黑树这种结构

collection(list,set,map)、HashMap

断了今生、忘了曾经 提交于 2020-02-18 02:53:39
collection里面有什么子类?(list和set是实现了collection接口的。)   List: 1.可以允许重复的对象(可重复,有序集合)。 2.可以插入多个null元素。 3.常用的实现类有 ArrayList、LinkedList 和 Vector。ArrayList 最为流行,它提供了使用索引的随意访问,而 LinkedList 则对于经常需要从 List 中添加或删除元素的场合更为合适。 ———————————————— Set: 1.不允许重复对象(不可重复,无序集合)。 2 只允许一个 null 元素 3.Set 接口最流行的几个实现类是 HashSet、LinkedHashSet 以及 TreeSet。最流行的是基于 HashMap 实现的 HashSet;TreeSet 还实现了 SortedSet 接口,因此 TreeSet 是一个根据其 compare() 和 compareTo() 的定义进行排序的有序集合。而且可以重复。 ———————————————— Map: 1.Map不是collection的子接口或者实现类。Map是一个接口。 2.不允许重复元素。 3. Map 里你可以拥有随意个 null 值但只能有一个 null (key)键。 4. Map 接口最流行的几个实现类是 HashMap、LinkedHashMap、Hashtable

HashMap 实现原理及源码分析

偶尔善良 提交于 2020-02-18 00:43:39
HashMap是JDK中非常重要的容器,采用 数组 + 链表 的方式实现,理想情况下能支持 O(1) 时间复杂度的增删改查操作。本文将由浅入深地讲解哈希表的实现原理,并对HashMap的部分源码进行分析。 1. 从数组说起 数组应该是我们最先学习的数据结构,它是内存中一块连续的存储单元,因此计算机可以根据数组起始地址、元素长度和下标,计算出我们要访问的元素的地址,时间复杂度为 O(1) 。 以下代码定义了一个简单的 Student 类,假如我们要存储 20 个 Student 对象,我们希望能够在 O(1) 时间复杂度内,根据 studentID 找到相应的对象。 public class Student { public int studentID; public String name; public Student(int studentID, String name) { this.studentID = studentID; this.name = name; } } 如果我们要存储的 20 个 Student 对象的 studentID 刚好就是从 0 到 19,我们自然可以新建一个长度为 20 的 Student 数组 students,然后将对象的 studentID 作为数组下标,放到对应的 slot 里面,如下图所示。这样的话,如果我们想找 studentID