hashcode

HashMap分析

眉间皱痕 提交于 2020-03-03 16:51:36
目录 存储结构 初始化 put resize 树化 get 为什么HashMap中equals()和hashCode()要同时重写? 为何HashMap的数组长度一定是2的次幂? 线程安全 参考 存储结构 JDK1.8前是数组+链表,JDK1.8之后是数组+链表+红黑树。本文分析基于JDK1.8源代码。 HashMap的基础结构是Node ,它存着hash、键值对,Node类型的指针next。 主干是桶数组,链表bin用于解决hash冲突,当链表的Node超过阈值(8),执行树化操作,将该链表改造成红黑树。 图片来源:Java核心技术36讲 初始化 HashMap有4个构造器,其他构造器如果用户没有传入initialCapacity (容量)和loadFactor(负载因子)这两个参数, 会使用默认值 ,initialCapacity默认为16,loadFactory默认为0.75。 基于lazy-load原则,主干数组table的内存空间分配不在初始化中,而是在put中。 public HashMap(int initialCapacity, float loadFactor) { if (initialCapacity < 0) throw new IllegalArgumentException("Illegal initial capacity: " +

集合——HashMap的工作原理

我只是一个虾纸丫 提交于 2020-03-03 16:19:27
http://www.importnew.com/16301.html 好的链接 HashMap的工作原理? 1. HashMap的底层结构是 数组加链表 ; a.HashMap包含一个Entry(key,value,next,hash)的内部类,key/value放入HashMap 的时候都会被包装成Entry的 对象 b.HashMap成员就有Entry数组,该数组的大小默认是16,永远都是2的次方数,如果自己给出的不是 2的次方数会转换成大 于并接近自己给的2 的次方数。 put(key,value)就是转换成Entry对象并放入数组中。 2.put方法的实现; c.1 根据key的HashCode进行Hash运算,得到hash值 c.2 根据hash值去确定数组的位置, hash&(table.length-1)等价于hash%(table.length) length是2的次方数该 公式成立, 正获取数组的位置 <bucket>。 c.3 如果这个位置没有元素存在,直接包装成Entry实例,给元素数组附值; 如果计算出的位置有元素已经存在,就会判断key是否相同,如果相同就会覆盖,并且遍历整个链表 如果都不覆盖插入到链表的头部 。 for (Entry<K,V> e = table [ i ]; e != null ; e = e . next ) 注意1

预备役3.1学习总结

女生的网名这么多〃 提交于 2020-03-02 00:41:33
1.上午 看Java视频 看到了 HashMap 有关内容,与昨天看的散列查找很少相似 哈希表的基本结构就是“数组+链表” 我们的目的是将”key-value两个对象”成对存放到HashMap的Entry[]数组中 (1) 获得key对象的hashcode 首先调用key对象的hashcode()方法,获得hashcode。 (2) 根据hashcode计算出hash值(要求在[0, 数组长度-1]区间) hashcode是一个整数,我们需要将它转化成[0, 数组长度-1]的范围。我们要求转化后的hash值尽量均匀地分布在[0,数组长度-1]这个区间,减少“hash冲突” i. 一种极端简单和低下的算法是: hash值 = hashcode/hashcode; 也就是说,hash值总是1。意味着,键值对对象都会存储到数组索引1位置,这样就形成一个非常长的链表。相当于每存储一个对象都会发生“hash冲突”,HashMap也退化成了一个“链表”。 ii. 一种简单和常用的算法是(相除取余算法): hash值 = hashcode%数组长度 这种算法可以让hash值均匀的分布在[0,数组长度-1]的区间。 早期的HashTable就是采用这种算法。但是,这种算法由于使用了“除法”,效率低下。JDK后来改进了算法。首先约定数组长度必须为2的整数幂,这样采用位运算即可实现取余的效果

HashMap原理分析及性能优化

╄→гoц情女王★ 提交于 2020-03-01 22:17:36
文章目录 一.HashMap是什么 二.HashMap继承类对比分析 三.HashMap源码相关单词含义 四.HashMap如何确定哈希桶数组索引位置 五. HashMap 的 put 方法分析 六.HashMap扩容机制 七.HashMap线程安全性 一.HashMap是什么 HashMap是Java程序员使用频率最高的用于映射(键值对)处理的数据类型。 HashMap是一个用于存储Key-Value键值对的集合,每一个键值对也叫做Entry。 这些个键值对(Entry)分散存储在一个数组当中,这个数组就是HashMap的主干。 数据结构(JDK1.8): Node<K,V>[] table; 数组+链表+红黑树 二.HashMap继承类对比分析 Java为数据结构中的映射定义了一个接口java.util.Map,此接口主要有四个常用的实现类,分别是 HashMap、Hashtable、LinkedHashMap和TreeMap , 类继承关系如下图所示: ① HashMap :它 根据键的hashCode值存储数据 ,大多数情况下可以直接定位到它的值,因而具有很快的访问速度,但遍历顺序却是不确定的。 HashMap最多只允许一条记录的键为null,允许多条记录的值为null。 HashMap非线程安全 ,即任一时刻可以有多个线程同时写HashMap,可能会导致数据的不一致

Java基础知识

时光怂恿深爱的人放手 提交于 2020-03-01 19:38:43
1 面向对象和面向过程的区别 面向过程:   优点:性能高。直接编译。   适用:单片机、嵌入式开发、Linux/Unix 面向对象:   特点:封装、继承、多态   优点:易维护、易复用、易扩展、可移植(数据类型、跨平台)   缺点:性能低。调用类时需要实例化、开销大、消耗资源。其次是半编译语言,最终的执行代码并不是可以被直接被CPU执行的二进制机械码。 2 java语言的特点   a. 面向对象(封装、继承、多态)   b. 平台无关性:由JVM实现,“一次编译,随处运行”   c. 支持多线程、网络编程等功能;   d. 编译和解释并行:解释是运行时翻译成机器代码     解释:JVM类加载器加载字节码文件,通过解释器逐行解释执行,执行速度较慢。     编译:有些代码块和方法经常被调用(热点代码)。         JIT(Just In Time)编译器属于运行时编译。第一次编译后,会将字节码对应的机器代码保存下来,下次可以直接使用。执行效率高。编译的是热点代码。 3 JVM、JDK、JRE   JVM是运行java字节码(.class文件)的虚拟机。实现跨平台。    JDK:java开发工具。可以创建和编译程序。   JRE:java运行时环境。 4 Java和C++的区别   共同:都是面向对象的语言   访问内存:c++支持指针访问内存   继承:c+

Java中equals和hascode之间的关系

懵懂的女人 提交于 2020-03-01 16:16:26
在逛 programcreek 的时候,我发现了一些专注细节但价值连城的主题。比如说:Java 的 equals() 和 hashCode() 是远房亲戚吗?像这类灵魂拷问的主题,非常值得深入地研究一下。 另外,我想要告诉大家的是,研究的过程非常的有趣,就好像在迷宫里探宝一样,起初有些不知所措,但经过一番用心的摸索后,不但会找到宝藏,还会有一种茅塞顿开的感觉,非常棒。 对于绝大多数的初级程序员或者说不重视“内功”的老鸟来说,往往停留在“知其然不知其所以然”的层面上——会用,但要说底层的原理,可就只能挠挠头双手一摊一张问号脸了。 很长一段时间内,我,沉默王二也一直处于这种层面上。但我决定改变了,因为“内功”就好像是在打地基,只有把地基打好了,才能盖起经得住考验的高楼大厦。借此机会,我就和大家一起,对“equals() 和 hashCode()”进行一次深入地研究。 equals() 和 hashCode() 是 Java 的超级祖先类 Object 定义的两个重要的方法: public boolean equals (Object obj) public int hashCode () 讲道理,单从方法的定义上来看, equals() 和 hashCode() 这两个方法之间没有任何亲戚关系,远房都够不上资格。但往深处扒拉,它们之间还真的是有千丝万缕的关系。到底是什么关系呢

HashMap的工作原理及HashMap和Hashtable的区别

我怕爱的太早我们不能终老 提交于 2020-03-01 14:59:10
HashMap的工作原理是近年来常见的Java面试题。几乎每个Java程序员都知道HashMap,都知道哪里要用HashMap,知道Hashtable和HashMap之间的区别,那么为何这道面试题如此特殊呢?是因为这道题考察的深度很深。这题经常出现在高级或中高级面试中。投资银行更喜欢问这个问题,甚至会要求你实现HashMap来考察你的编程能力。ConcurrentHashMap和其它同步集合的引入让这道题变得更加复杂。让我们开始探索的旅程吧! 先来些简单的问题 “你用过HashMap吗?” “什么是HashMap?你为什么用到它?” 几乎每个人都会回答“是的”,然后回答HashMap的一些特性,譬如HashMap可以接受null键值和值,而Hashtable则不能;HashMap是非synchronized;HashMap很快;以及HashMap储存的是键值对等等。这显示出你已经用过HashMap,而且对它相当的熟悉。但是面试官来个急转直下,从此刻开始问出一些刁钻的问题,关于HashMap的更多基础的细节。面试官可能会问出下面的问题: “你知道HashMap的工作原理吗?” “你知道HashMap的get()方法的工作原理吗?” 你也许会回答“我没有详查标准的Java API,你可以看看Java源代码或者Open JDK。”“我可以用Google找到答案。”

java中的包装类

一个人想着一个人 提交于 2020-03-01 10:11:34
java中有8种基本的数据类型,其中每一种数据类型都对应了一种包装类。java是纯面向对象的语言,在java中的一切东西都可以用对象的形式表示,包括java中的基本数据类型。包装类中除了Integer和Character外,其他的包装类都是以java中的基本数据类型的首字母大写命名的。 每个包装类中都有一个静态的方法来将java的基本数据类型转换为包装类,这个静态方法接受一个对应的基本类型参数然后返回一个包装类的引用: int i = 10; Integer i1 = Integer.valueOf(i); 还有一个实例方法xxxValue()返回该包装类对应的基本数据类型: Integer i1 = new Integer(1); int i2 = i1.intValue(); 其中把基本的数据类型转换成包装类型我们习惯将其称之为装箱,把包装类型转换为基本类型我们称之为拆箱。在java5之后java引入了自动装箱和拆箱,我们在代码中可以直接把基本数据赋值給包装类由java编译器来帮我们调用对应的valueOf方法和xxxValue方法。 在包装类中除了toString方法还有几个常用的和String有关的方法。除了Character外,每个包装类中都有一个静态的ValueOf(String s)方法接受一个字符串返回一个包装类。 Integer i2 = Integer

java中关于equals,==和hashCode的一些问题

旧巷老猫 提交于 2020-03-01 04:57:29
首先要明确一个问题,Java中变量类型分为值类型和引用类型。值类型是存储在内存中的堆栈(以后简称栈),而引用类型的变量在栈中仅仅是存储引用类型变量的地址,而其本身则存储在堆中。在调用方法传参数的时候,值类型传的是值,而引用类型传的是地址(这相当于C++中的传指针)。先看下面的代码: public class Test{ public static void main(String[] args) { String str = "123"; changeStr(str); System.out.println(str); } public static void changeStr(String str){ str="welcome"; } } 输出结果:123 输出结果不是“welcome”。我们可以从C++的角度去理解:当参数是某个指针时,形参只是实参的一个副本,即实参把地址复制给形参,然后就没什么事了。方法本身只会改变形参的内容,即指针所指向的对象的内容,而不会改变实参的内容,即指针的指向不会改变。str="welcome";这行代码改变了指针的指向,但是对于方法外的原来的实参,是没影响的。 扯远了,下面讨论==,equals的问题。 ==操作比较的是两个变量的值是否相等,对于引用型变量表示的是两个变量在堆中存储的地址是否相同,即栈中的内容是否相同。

java中==与equel的区别

拜拜、爱过 提交于 2020-03-01 04:53:12
值类型是存储在内存中的堆栈(以后简称栈),而引用类型的变量在栈中仅仅是存储引用类型变量的地址,而其本身则存储在堆中。 ==操作比较的是两个变量的值是否相等,对于引用型变量表示的是两个变量在堆中存储的地址是否相同,即栈中的内容是否相同。 equals操作表示的两个变量是否是对同一个对象的引用,即堆中的内容是否相同。 ==比较的是2个对象的地址,而equals比较的是2个对象的内容。 显然,当equals为true时,==不一定为true; 一、String中的equals和== 1、 public class TestString { public static void main(String[] args) { String s1 = "Monday"; String s2 = "Monday"; } } 上面这段程序中,到底有几个对象呢? 来检测一下吧,稍微改动一下程序 public class TestString { public static void main(String[] args) { String s1 = "Monday"; String s2 = "Monday"; if (s1 == s2) System.out.println("s1 == s2"); else System.out.println("s1 != s2"); } } 编译并运行程序