hashcode

浅谈hashCode

只谈情不闲聊 提交于 2020-01-09 00:55:18
《Java编程思想》中对hashCode的描述: 设计hashCode()时最重要的因素就是:无论何时,对同一个对象调用hashCode()都应该产生同样的值。如果将一个对象用put()添加进HashMap时产生一个hashCdoe()值,而用get()取出时却产生了另一个hashCode()值,那么就无法重新取得该对象了。所以如果你的hashCode()方法依赖于对象中易变的数据,用户就要当心了,因为此数据发生变化时,hashCode()方法就会生成一个不同的散列码,相当于产生了一个不同的键。 1. HashCode源代码分析 1.1 Object中的HashCode源代码 public int hashCode() { int lockWord = shadow$_monitor_; final int lockWordStateMask = 0xC0000000; // Top 2 bits. final int lockWordStateHash = 0x80000000; // Top 2 bits are value 2 (kStateHash). final int lockWordHashMask = 0x0FFFFFFF; // Low 28 bits. if ((lockWord & lockWordStateMask) == lockWordStateHash

关于hashcode和equals方法说明

扶醉桌前 提交于 2020-01-08 11:11:31
一、前言 我们都知道,要比较两个对象是否相等时需要调用对象的equals()方法,即判断对象引用所指向的对象地址是否相等,对象地址相等时,那么与对象相关的对象句柄、对象头、对象实例数据、对象类型数据等也是完全一致的,所以我们可以通过比较对象的地址来判断是否相等。 二、Object源码理解 对象在不重写的情况下使用的是Object的equals方法和hashcode方法,从Object类的源码我们知道,默认的equals 判断的是两个对象的引用指向的是不是同一个对象;而hashcode也是根据对象地址生成一个整数数值; 另外我们可以看到Object的hashcode()方法的修饰符为native,表明该方法是否操作系统实现,java调用操作系统底层代码获取哈希值。 public class Object { public native int hashCode(); /** * Indicates whether some other object is "equal to" this one. * <p> * The {@code equals} method implements an equivalence relation * on non-null object references: * <ul> * <li>It is <i>reflexive</i>: for any

【原创】够强!一行代码就修复了我提的Dubbo的Bug。

£可爱£侵袭症+ 提交于 2020-01-08 00:01:19
这是 why 技术的第 28 篇原创文章 之前在 《Dubbo 一致性哈希负载均衡的源码和 Bug,了解一下?》中写到了我发现了一个 Dubbo 一致性哈希负载均衡算法的 Bug。 对于解决方案我是这样写的: 特别简单,把获取identityHashCode的方法从System.identityHashCode(invokers)修改为invokers.hashCode()即可。此方案是我提的issue里面的评论,这里System.identityHashCode和 hashCode之间的联系和区别就不进行展开讲述了,不清楚的大家可以自行了解一下。 我说: 这里 System.identityHashCode 和 hashCode 之间的联系和区别就不进行展开讲述了,不清楚的大家可以自行了解一下。 但是有读者在后台问我详细原因,我已经和他聊清楚了。 再加上这个 BUG 已于近期修复了,且只用了一行代码就修复了 ,那我就写一下解决方案,以及背后的原理。 即是对之前文章的一个补充,也是一个独立的知识点。 所以本文主要是回答下面这三个问题: 1.什么是 System.identityHashCode? 2.什么是 hashCode? 3.为什么一行代码就修复了这个 BUG? 注:本文 Dubbo 源码 2.7.4.1 版本。如果阅读过 《Dubbo 一致性哈希负载均衡的源码和 Bug

Integer a = 200,b=200比较详解

冷暖自知 提交于 2020-01-07 21:40:53
题记:前几天面试Java基础给来了个面试题Integer a=200,b=200;System.out.println(a==b);当时回答是false,后来面试官又来了一个Integer a=100,b=100;System.out.println(a==b);这个回答的也是false当时面试官笑笑说恭喜你回答错误,当时一愣回来才想起int的范围,特做此笔记以做记录; 补充: Java如何查看对象的内存地址?Java是使用hashcode来表示对象的内存地址,两个相同的对象的hashcode是相同的,我们可以使用System.identityHashCode(传输进去的参数是一个对象)打印对象的hashcode值。 分析: 我们都知道基本类型通过==比较的是他们的值大小,而引用类型比较的是他们的引用地址 这里肯定你也会和我有一样的疑问为什么200的时候是false,100的时候是true,应该Integer包装对象都是比较的应该是内存的地址都应该是false才对啊!这里请看源码: 当我们给一个Integer赋予一个int类型的时候会调用Integer的静态方法valueOf。 由源码我们可以看到Integer的范围是“-128~127”,当i在这个范围内是从IntegerCache中直接获取,当超越这个范围才会new 一个新的Integer对象 1 @Test 2 public

Map

久未见 提交于 2020-01-07 21:20:58
Hashtable、HashMap、TreeMap有何不同 HashTable是一个早期的集合类型,所以在继承扩展上是有区别的。 大部分使用Map的场景,通常就是放入、访问或者删除,而对顺序没有特别要求,HashMap在这种情况下基本是最好的选择。HashMap的性能表现非常依赖于哈希码的有效性,请务必 掌握hashCode和equals的一些基本约定,比如: 1.equals相等的对象,hashCode也一定相等。因为我们是我们是通过hash得到对象所在的“链表节点”,然后再进行equals对比的,所以相同的hashCode不一定equals相等,但是反之必然。实际上来讲,单纯的hash不满足很多业务需求,因此扩展出了一种一致性哈希,这个在外文翻译里有一篇。 https://medium.com/ably-realtime/how-to-implement-consistent-hashing-efficiently-fe038d59fff2 2.重写了hashCode也一定要重写equals,实际上不建议自己重写,因为并非比较简单的事情。 3.hashCode需要保持一致性,状态改变返回的哈希值仍然要一致。 4.equals的一些对称反射传递特性 TreeMap和LinkedHashMap保证存放顺序是不同的 public class LinkedHashMapTest {

java基础面试题

末鹿安然 提交于 2020-01-07 09:51:29
谈谈你对java平台的理解?java是解释执行,这句话正确吗? 答:java本身是一种面向对象的语言,最显著特性是2个方面,1是书写一次,到处运行即跨平台,另外1个是垃圾回收,java通过垃圾收集器回收分配的内存,大部分情况下,程序员不需要自己操作内存的分配和回收。 对于java是解释执行这句话,说法不太正确,我们开发的java源码即.java文件,首先通过javac编译器编译为字节码,然后运行时,通过jvm内嵌的解释器将字节码转换为最终的机器码,但常见jvm,eg:oracle jdk提供的Hotspot jvm,都提供了JIT(Just-in-time)编译器即动态编译器。JIT能够在运行时将热点代码编译成机器码,这种情况下部分热点代码就属于编译执行,而非解释执行。 JDK 和 JRE 有什么区别? JDK:Java Development Kit 的简称,java 开发工具包,提供了 java 的开发环境和运行环境。 JRE:Java Runtime Environment 的简称,java 运行环境,为 java 的运行提供了所需环境。 具体来说 JDK 其实包含了 JRE,同时还包含了编译 java 源码的编译器 javac,还包含了很多 java 程序调试和分析的工具。简单来说:如果你需要运行 java 程序,只需安装 JRE 就可以了,如果你需要编写 java 程序

Why we need to override hashCode and equals?

馋奶兔 提交于 2020-01-07 09:47:09
问题 By default hashCode and equals works fine. I have used objects with hash tables like HashMap, without overriding this methods, and it was fine. For example: public class Main{ public static void main(String[] args) throws Exception{ Map map = new HashMap<>(); Object key = new Main(); map.put(key, "2"); Object key2 = new Main(); map.put(key2, "3"); System.out.println(map.get(key)); System.out.println(map.get(key2)); } } This code works fine. By default hashCode returning memory address of

Hashmap1.7和1.8区别+ConcurrentHashmap1.7和1.8区别

拟墨画扇 提交于 2020-01-06 16:32:43
Hashmap JDK1.7中 使用一个Entry数组来存储数据,用key的hashcode取模来决定key会被放到数组里的位置,如果hashcode相同,或者hashcode取模后的结果相同,那么这些key会被定位到Entry数组的同一个格子里,这些key会形成一个链表; 在hash函数特别差的情况下,比如说所有key的hashcode都相同,这个链表可能会很长,那么put/get操作都可能需要遍历这个链表,也就是最差情况下时间复杂度为O(n)。 JDK1.8中 使用一个Node数组来存储数据,但是这个Node可能是链表结构,也可能是红黑树结构;如果插入的元素key的hashcode值相同,那么这些key也会被定位到Node数组的同一个格子里,如果不超过8个使用链表存储,超过8个,会调用treeifyBin函数,将链表转换为红黑树。那么即使所有key的hashcode完全相同,由于红黑树的特点,查找某个特定元素,也只需要O(logn)的开销。 红黑树: 每个节点不是红的就是黑的; 根节点是黑的; 叶节点都是黑色,叶子节点指的是为空的节点; 如果一个节点是红色的,那么子节点必须为黑色; 从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑节点。 ConcurrentHashMap JDK1.7中 使用segment+hashentry来实现

Set集合

主宰稳场 提交于 2020-01-05 04:16:04
Set接口是Collection接口的子接口,Set集合是无序的(但子类中有很多都是有序的),不能有重复的元素,如果用add()加入一个已有的元素,会添加失败,返回false。 Set接口的继承关系: Set接口的常用实现类: 1、HashSet 按Hash算法来存储元素,具有良好的存储、查找性能。 元素无序,就是说排列顺序和添加顺序可能不同 不是同步的,如果多个线程同时访问、修改一个HashSet,必须要使用同步代码来保证同步。就是说HashSet不是线程安全的。 元素的值可以是null HashSet添加元素(存储)的机制: 先调用该元素的hashCode()方法获取hashCode值,根据hashCode值确定存储位置。 如果该位置上没有元素,则说明HashSet集合中没有与之相同的元素,直接在该位置存储该元素。 如果该位置已有元素,则使用equals()比较这两个元素,返回false则在此位置存储该元素(但这样会在一个位置存储多个元素,导致HashSet性能降低),返回true则添加失败,不存储此元素。 hash,被翻译为哈希、散列。hash算法的价值在于速度,它能快速查找被检索的对象。查询某个元素时,根据hashCode值直接定位元素的存储位置,实现快速查找。如果在HashSet中有多个元素的hashCode相同(在一个位置存储了多个元素),会导致查找性能下降。

Why does Object.hashcode() have conflicts in Java?

五迷三道 提交于 2020-01-04 08:05:52
问题 I run the code below in Hotspot JDK 1.6 on Windows XP, I ran it twice and I got the results below. So basically it seems the object.hashcode() also have conflicts? it looks like it's not returning the memory address in the VM. However, a comment in the JDK said the values should be distinct, can anyone explain? As much as is reasonably practical, the hashCode method defined by class Object does return distinct integers for distinct objects. (This is typically implemented by converting the