-
2019-02-01 23:37:03
原文地址
Java的Object类中有一个方法:public native int hashcode();
hashcode方法的作用
对于包含容器类型的程序设计语言来说,基本上都会涉及到hashCode。在Java中也一样,hashCode方法的主要作用是为了配合基于散列的集合一起正常运行,这样的散列集合包括HashSet、HashMap以及HashTable。
为什么这么说呢?考虑一种情况,当向集合中插入对象时,如何判别在集合中是否已经存在该对象了?(注意:集合中不允许重复的元素存在)
也许大多数人都会想到调用equals方法来逐个进行比较,这个方法确实可行。但是如果集合中已经存在一万条数据或者更多的数据,如果采用equals方法去逐一比较,效率必然是一个问题。此时hashCode方法的作用就体现出来了,当集合要添加新的对象时,先调用这个对象的hashCode方法,得到对应的hashcode值,实际上在HashMap的具体实现中会用一个table保存已经存进去的对象的hashcode值,如果table中没有该hashcode值,它就可以直接存进去,不用再进行任何比较了;如果存在该hashcode值, 就调用它的equals方法与新元素进行比较,相同的话就不存了,不相同就散列其它的地址,所以这里存在一个冲突解决的问题,这样一来实际调用equals方法的次数就大大降低了,说通俗一点:Java中的hashCode方法就是根据一定的规则将与对象相关的信息(比如对象的存储地址,对象的字段等)映射成一个数值,这个数值称作为散列值。
有些朋友误以为默认情况下,hashCode返回的就是对象的存储地址,事实上这种看法是不全面的,确实有些JVM在实现时是直接返回对象的存储地址,但是大多时候并不是这样,只能说可能存储地址有一定关联。
因此有人会说,可以直接根据hashcode值判断两个对象是否相等吗?肯定是不可以的,因为不同的对象可能会生成相同的hashcode值。虽然不能根据hashcode值判断两个对象是否相等,但是可以直接根据hashcode值判断两个对象不等,如果两个对象的hashcode值不等,则必定是两个不同的对象。如果要判断两个对象是否真正相等,必须通过equals方法。
也就是说对于两个对象,如果调用equals方法得到的结果为true,则两个对象的hashcode值必定相等;
如果equals方法得到的结果为false,则两个对象的hashcode值不一定不同;
如果两个对象的hashcode值不等,则equals方法得到的结果必定为false;
如果两个对象的hashcode值相等,则equals方法得到的结果未知。
equals方法和hashCode方法
在重写equals方法的同时,必须重写hashCode方法。目的是让equals方法和hashCode方法始终在逻辑上保持一致性。
在设计hashCode方法和equals方法的时候,如果对象中的数据易变,则最好在equals方法和hashCode方法中不要依赖于该字段。
更多相关内容 -
hashCode 原理
2021-02-25 20:20:31网上一般都说hashCode 就是对象的内存地址,但是你想下垃圾回收时(复制算法,整理算法)都要发生对象移动,都要改变对象的内存地址。但hashCode又不能变化,那么该值一定是被保存在对象的某个地方了。 hashcode就是...网上一般都说hashCode 就是对象的内存地址,但是你想下垃圾回收时(复制算法,整理算法)都要发生对象移动,都要改变对象的内存地址。但hashCode又不能变化,那么该值一定是被保存在对象的某个地方了。
hashcode就是保存在对象头里面的,但是如果hashcode是内存地址的话,那么就有可能会重复到之前回收对象的地址。对象头详解见此文章
苍天可见,hashcode绝对不是简简单单的内存地址。
hashcode的6种生成策略
可以通过在JVM启动参数中添加-XX:hashCode=4,改变默认的hashCode计算方式。
1. hashCode=0
if (hashCode == 0) { value = os::random() ; }
此类方案返回一个Park-Miller伪随机数生成器生成的随机数OpenJdk 6 &7的默认实现。
2. hashCode=1
if (hashCode == 1) { intptr_t addrBits = cast_from_oop<intptr_t>(obj) >> 3 ; value = addrBits ^ (addrBits >> 5) ^ GVars.stwRandom ; }
此类方案将对象的内存地址,做移位运算后与一个随机数进行异或得到结果。
3. hashCode = 2
if (hashCode == 2) { value = 1 ; // for sensitivity testing }
此类方案返回固定的1。
4. hashCode = 3
if (hashCode == 3) { value = ++GVars.hcSequence ; }
此类方案返回一个自增序列的当前值。
5. hashCode = 4
if (hashCode == 4) { value = cast_from_oop<intptr_t>(obj) ; }
此类方案返回当前对象的内存地址。
6. hashCode 为 其它
通过和当前线程有关的一个随机数+三个确定值,运用Marsaglia’s xorshift scheme随机数算法得到的一个随机数。JDK8 的默认hashCode的计算方法就是这个xorshift 算法。
测试hashcode是不是内存地址
首先有个工具类:利用Unsafe类 打印真实内存地址
public static class Memory { static final Unsafe unsafe = getUnsafe(); static final boolean is64bit = true; public static void printAddresses(Object... objects) { long last = 0; int offset = unsafe.arrayBaseOffset(objects.getClass()); int scale = unsafe.arrayIndexScale(objects.getClass()); switch (scale) { case 4: long factor = is64bit ? 8 : 1; final long i1 = (unsafe.getInt(objects, offset) & 0xFFFFFFFFL) * factor; System.out.print(Long.toHexString(i1)); last = i1; for (int i = 1; i < objects.length; i++) { final long i2 = (unsafe.getInt(objects, offset + i * 4) & 0xFFFFFFFFL) * factor; if (i2 > last) System.out.print(", +" + Long.toHexString(i2 - last)); else System.out.print(", -" + Long.toHexString(last - i2)); last = i2; } break; case 8: throw new AssertionError("Not supported"); } System.out.println(); } private static Unsafe getUnsafe() { try { Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe"); theUnsafe.setAccessible(true); return (Unsafe)theUnsafe.get(null); } catch (Exception e) { throw new AssertionError(e); } } }
main方法
public static void main(String[] args) throws Exception { Object o = new Object(); Memory.printAddresses(o); System.err.println(Long.toHexString(o.hashCode())); System.err.println(Long.toHexString(System.identityHashCode(o))); }
打印结果
76b8b4c28 4e25154f 4e25154f
hashCode 跟 System.identityHashCode 方法一样,但是跟内存地址没半毛钱关系。
我们在改变main方法
public static void main(String[] args) throws Exception { Object o1 = new Object(); Object o2 = new Object(); Memory.printAddresses(o2); System.err.println(Long.toHexString(o2.hashCode())); System.err.println(Long.toHexString(System.identityHashCode(o2))); }
打印结果
76b8b4c58 4e25154f 4e25154f
很奇怪,我们定义了两个对象,打印第二个对象内存地址和第一次打印的不同,这很正常。
但是打印hashcode确实跟第一次完全一样,由此可见hashcode值跟对象没关系,可能就是分配好的数列,你构造了一个对象就顺序取取数列中的数作为hashcode。
hashcode什么时候生成,在哪分配给对象的 还请大神知道的留言给我!!!!谢谢~~
再来欣赏几个面试题
1、equals()既然已经能实现对比的功能了,为什么还要hashCode()呢?
因为重写的equals()里一般比较的比较全面比较复杂,这样效率就比较低,而利用hashCode()进行对比,则只要生成一个hash值进行比较就可以了,效率很高。
2、hashCode()既然效率这么高为什么还要equals()呢?
因为hashCode()并不是完全可靠,有时候不同的对象他们生成的hashcode也会一样(生成hash值得公式可能存在的问题),所以hashCode()只能说是大部分时候可靠,并不是绝对可靠,所以我们可以得出:
equals()相等的两个对象他们的hashCode()肯定相等,也就是用equals()对比是绝对可靠的。
hashCode()相等的两个对象他们的equals()不一定相等,也就是hashCode()不是绝对可靠的。
3、为什么要重写 hashcode 和 equals 方法?
因为原生的hashcode和equals 只是比较类似内存地址的唯一值,也就是说必须是new出的同个对象才返回相等,跟对象里的业务值没关系。 但是有的场景比如订单对象,很明显当订单号相同的两个订单对象就应该是相等的,于是我们需要重写hashcode 和equals 只判断订单号相等则对象相等。
Hashcode的位移优化
一些位运算符介绍
<< : 左移运算符,num << 1,相当于num乘以2 低位补0。 >> : 右移运算符,num >> 1,相当于num除以2 高位补0。 >>> : 无符号右移,忽略符号位,空位都以0补齐。 % : 模运算 取余。 ^ : 位异或 第一个操作数的的第n位于第二个操作数的第n位相反,那么结果的第n为也为1,否则为0。 & : 与运算 第一个操作数的的第n位于第二个操作数的第n位如果都是1,那么结果的第n为也为1,否则为0。 | : 或运算 第一个操作数的的第n位于第二个操作数的第n位 只要有一个是1,那么结果的第n为也为1,否则为0。 ~ : 非运算 操作数的第n位为1,那么结果的第n位为0,反之,也就是取反运算(一元操作符:只操作一个数)。
String类的hashcode方法
public int hashCode() { int h = hash; if (h == 0 && value.length > 0) { // 保证只计算一次,之后直接取hash 这个缓存 char val[] = value; for (int i = 0; i < value.length; i++) { h = 31 * h + val[i]; } hash = h; } return h; }
31*h可以被编译器优化为 h左移5位后减h , 因为31 二进制是 11111, 有较高的性能。
之所以是31原因就是,选太小的质数移位后也是区间很小,hash冲突高,如果选择很大的质数,移位后会导致区间数很大,超出int的范围,而String的hash就是用int存储的。
其它的原因我也讲不出来,还是请各位看下大佬的解释吧,也请大佬跟我留言解释下为什么就是31,感谢大佬
强烈推荐一套Java进阶博客,都是干货,走向架构师不是梦!
-
Java基础之hashcode剖析
2022-02-21 18:49:08在 Java 中,高效的散列算法支持一些最流行的集合,例如HashMap和HashSet,在本文中,我们将重点介绍hashCode() 的工作原理、它如何在集合中使用以及如何正确实现它。 2. hashcode 原理 2.1 Java equals()和...1. 前言
散列是计算机科学的一个基本概念。在 Java 中,高效的散列算法支持一些最流行的集合,例如HashMap和HashSet,在本文中,我们将重点介绍hashCode() 的工作原理、它如何在集合中使用以及如何正确实现它。
2. hashcode 原理
2.1 Java equals()和hashCode()的关系
Object.html#hashCode()
hashcode的理解
- hashCode的存在主要是用于查找的快捷性,如Hashtable,HashMap等,hashCode是用来在散列存储结构中确定对象的存储地址的;
- 如果两个对象相同,就是适用于equals(java.lang.Object) 方法,那么这两个对象的hashCode一定要相同;
- 如果对象的equals方法被重写,那么对象的hashCode也尽量重写,并且产生hashCode使用的对象,一定要和equals方法中使用的一致,否则就会违反上面提到的第2点;
- 两个对象的hashCode相同,并不一定表示两个对象就相同,也就是不一定适用于equals(java.lang.Object) 方法,只能够说明这两个对象在散列存储结构中,如Hashtable,他们 “存放在同一个篮子里” 。
再归纳一下就是 hashCode是用于查找使用的,而 equals是用于比较两个对象的是否相等的。以下这段话是从别人帖子回复拷贝过来的,说得很形象:
(1) hashcode是用来查找的,如果你学过数据结构就应该知道,在查找和排序说过:假如内存中有这样的位置 [0 1 2 3 4 5 6 7] 而我有个类,这个类有个字段叫ID,我要把这个类存放在以上8个位置之一,如果不用hashcode而任意存放,那么当查找时就需要到这八个位置里挨个去找,或者用类似二分法的算法。 但如果用hashcode那就会使效率提高很多。
我们这个类中有个字段叫ID,那么我们就定义我们的hashcode为ID%8,然后把我们的类存放在取得得余 数那个位置。比如我们的ID为9,9除8的余数为1,那么我们就把该类存在1这个位置,如果ID是13,求得 的余数是5,那么我们就把该类放在5这个位置。这样,以后在查找该类时就可以通过ID和8求余数直接找到 存放的位置了。
(2) 但是如果两个类有相同的hashcode该怎么办呢(假设上面的ID不是唯一的),假如 9%8=1,17%8=1,那么这是不是合法的呢?回答是:可以这样。
那么如何判断呢?在这个时候就需要定义 equals了。也就是说,我们先通过hashcode来判断两个类是否存放在一个桶里面,但是这个桶里面可以有很多类,那么我们就需要通过equals 来在这个桶里找到我们要的类。
那么。重写了equals(),为什么还要重写hashCode()呢?
想想,你要在一个桶里找东西,你必须先要找到这个桶啊,你不通过重写hashcode()来找到桶,光重写equals()有什么用啊
2.2 举例分析
package com.wxw.common.hashcode; import java.util.HashSet; import java.util.Set; /** * @author 公众号:Java半颗糖 * @desc: * @date: 2021/7/24 */ public class DemoHashCode { private int id; public void setId(Integer id) { this.id = id; } public Integer getId() { return id; } @Override public int hashCode() { return id % 10; } public static void main(String[] args) { DemoHashCode a = new DemoHashCode(); DemoHashCode b = new DemoHashCode(); a.setId(1); b.setId(1); Set<DemoHashCode> set = new HashSet<>(); set.add(a); set.add(b); System.out.println(a.hashCode() == b.hashCode()); System.out.println(a.equals(b)); System.out.println(set); /** * ---------- * 运行结果: * true * false * [com.wxw.common.hashcode.DemoHashCode@1, com.wxw.common.hashcode.DemoHashCode@1] */ } } 复制代码
以上这个示例,我们只重写了hashcode() 方法,从上面的结果可以看出,虽然两个对象的hashcode相等,但实际上两个对象并不相等。
我们没有重写 equals()方法,那么就会调用Object默认的equals()方法,是比较两个对象的引用是不是相同,实际上两个对象的引用肯定是不等的,这里我们将生成的对象放到了HashSet中,而HashSet中只能够存放唯一的对象,也就是相同的(适用于equals方法)的对象只会存放一个,但是这里实际上是两个对象a,b都被放到了HashSet中,这样HashSet就失去了他本身的意义了。 此时我们把equals方法给加上:
package com.wxw.common.hashcode; import java.util.HashSet; import java.util.Set; /** * @author 公众号:Java半颗糖 * @desc: * @date: 2021/7/24 */ public class DemoHashCode { private int id; public void setId(Integer id) { this.id = id; } public Integer getId() { return id; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; DemoHashCode that = (DemoHashCode) o; return id == that.id; } @Override public int hashCode() { return id % 10; } public static void main(String[] args) { DemoHashCode a = new DemoHashCode(); DemoHashCode b = new DemoHashCode(); a.setId(1); b.setId(1); Set<DemoHashCode> set = new HashSet<>(); set.add(a); set.add(b); System.out.println(a.hashCode() == b.hashCode()); System.out.println(a.equals(b)); System.out.println(set); /** * ---------- * 运行结果: * true * true * [com.wxw.common.hashcode.DemoHashCode@1] */ } } 复制代码
从结果我们可以看出,现在两个对象就完全相等了,HashSet中也只存放了一份对象。
3. hash 冲突
哈希表的内在行为也带来了相应的问题:即使使用有效的哈希算法,两个或多个对象可能具有相同的哈希码,即使两个对象不相等。因此,即使它们具有不同的散列值,它们的散列码也会指向同一个桶。 这种情况通常被称为散列冲突。
解决hash冲突的方法,详细分析可以点此处查看:
- 链表法
- 开放寻址法
Java中的hashMap是使用链表法解决hash冲突的
当两个或多个对象指向同一个存储桶时,它们只是存储在一个链表中。在这种情况下,哈希表是一个链表数组,每个具有相同哈希值的对象都附加到链表中的通索引处。
在最坏的情况下,几个桶会绑定一个链表,而对链表中对象的检索将是线性执行的。
处理哈希冲突 简言之,为什么高效地实现 hashCode()如此重要?
Java8 也为HashMap的实现进行了增强,如果桶大小超过8,节点入超过64,则会转换为红黑树,而不是使用链表,这样当链表太长接近线性查找(复杂度为O(n))时 用红黑树 O(logN) 代替。
3.1 hashmap和hashcode的联系
User类中我们重写hashcode方法
@Data public class User { private long userId; private String userName; private String email; @Override public int hashCode() { int hash = 7; hash = 31 * hash + (int) userId; hash = 31 * hash + (userName == null ? 0 : userName.hashCode()); hash = 31 * hash + (email == null ? 0 : email.hashCode()); System.out.println("hashCode() called - Computed hash: " + hash); return hash; } public User(Long userId, String userName, String email) { this.userId = userId; this.userName = userName; this.email = email; } } 复制代码
应用程序的入口:
public class DemoHashMap { public static void main(String[] args) { Map<User, User> users = new HashMap<>(); User user1 = new User(1L, "John", "john@domain.com"); User user2 = new User(2L, "Jennifer", "jennifer@domain.com"); User user3 = new User(3L, "Mary", "mary@domain.com"); users.put(user1, user1); users.put(user2, user2); users.put(user3, user3); if (users.containsKey(user1)) { System.out.print("User found in the collection"); } } } 复制代码
在这里,重要的是要注意,每次将对象存储在哈希映射中并使用containsKey() 方法检查时,都会调用hashCode() 并将计算出的哈希码打印到控制台:
结论
很明显,生成高效的hashCode() 实现通常需要混合一些数学概念(即素数和任意数)、逻辑和基本数学运算。但是我们也可以有效地实现hashCode(),只需要确保散列算法为不相等的对象生成不同的散列码,并且它与equals()* 的实现一致
-
HashCode原理
2018-10-31 07:56:58HashCode原理 原理 概念: 根据一定的规则将与对象相关的信息(比如对象的存储地址,对象的字段等)映射成一个数值,这个数值称作为散列值。 作用: 主要是保证基于散列的集合,如HashSet、HashMap以及...HashCode原理
- 原理
- 概念:
根据一定的规则将与对象相关的信息(比如对象的存储地址,对象的字段等)映射成一个数值,这个数值称作为散列值。
-
- 作用:
主要是保证基于散列的集合,如HashSet、HashMap以及HashTable等,在插入元素时保证元素不可重复,同时为了提高元素的插入删除便利效率而设计;主要是为了查找的便捷性而存在。
-
- 常见类别
- Integer.hashCode()即对应的int值;故equals相等则相等。
- String.equals()是根据具体的内容(实际的字符串),通过特定的算法计算出来的。
- Object.hashCode()是通过对应的地址计算。
- equals方法和hashCode方法
- 在重写equals方法的同时,必须重写hashCode方法
- 设计hashCode()原则
无论何时,对同一个对象调用hashCode()都应该产生同样的值。
如果两个对象根据equals方法比较是相等的,那么两个对象的hashCode方法返回的整数值必须相等。
如果两个对象根据equals方法比较是不等的,则hashCode方法不一定得返回不同的整数。
-
- 应用:哈希表
可以提供快速的插入操作和查找操作。数据的插入删除便利时间复杂度为O(1)
- 使用问题
- 哈希表中只覆盖equals()情况下,造成元素的重复性和本身设置的不符。
如在散列表中,当为了使满足某种条件的两个对象相等(例在属性相等则忽略地址均认为属于同一元素)情况下,重写了equsals()方法,而未重写hashCode()方法。但是散列表判断元素是否相同,是先通过hashCode一致后才equals()比较,则会出现bug。即要想保证元素的唯一性,必须同时覆盖hashCode和equals才行。
-
- 内存泄露:
在哈希表中元素添加之后,不能修改其与hashCode有关的信息(如用户自定义的hashCode()方法,该方法的值和具体的属性有关),防止remove等操作因元素桶的变化而失效的同时,在集合中进行大量的元素添加后修改值再进行remove移除,导致内存泄露。
qq_38331606 - 总结:
- Hashcode是为了提高元素在哈希表中的插入删除便利效率而设计的
- 为了保证程序的严谨性,必须同时覆盖hashCode和equals
- 在哈希表中元素添加之后,不能修改其与hashCode有关的信息,防止remove操作失效,发生内存泄露
- 如果两个对象根据equals方法比较是相等的,那么两个对象的hashCode方法返回的整数值必须相等。
- 哈希算法
是将数据依特定算法直接指定到一个地址上。
这样一来,当集合要添加新的元素时,先调用这个元素的HashCode方法,就一下子能定位到它应该放置的物理位置上。
(1)如果这个位置上没有元素,它就可以直接存储在这个位置上,不用再进行任何比较了;
(2)如果这个位置上已经有元素了,就调用它的equals方法与新元素进行比较,相同的话就不存了;
(3)不相同的话,也就是发生了Hash key相同导致冲突的情况,那么就在这个Hash key的地方产生一个链表,将所有产生相同HashCode的对象放到这个单链表上去,串在一起(很少出现)。这样一来实际调用equals方法的次数就大大降低了,几乎只需要一两次。
- 原理
-
Java中的HashCode(1)之hash算法基本原理
2021-03-12 19:49:55二、Hash算法原理 当Set接收一个元素时根据该对象的内存地址算出hashCode,看它属于哪一个区间,在这个区间里调用equeals方法。 确实提高了效率。但一个面临问题:若两个对象equals相等,但不在一个区间,根本没有... -
java基础----比较对象 hashcode 与 equals 与 ==
2021-03-22 18:48:25介绍hashcode和equals是Object类中定义的方法;hashCode 源码:public native int hashCode();equals()源码:public boolean equals(Object obj) {return (this == obj);}从equals源码可以看到 对于Object equals 和... -
Java自学-集合框架 hashCode原理
2019-06-01 12:42:36Java hashcode原理 步骤 1 : List查找的低效率 假设在List中存放着无重复名称,没有顺序的2000000个Hero 要把名字叫做“hero 1000000”的对象找出来 List的做法是对每一个进行挨个遍历,直到找到名字叫做“hero ... -
Java中equals()与hashCode()的原理与设计
2020-12-22 16:39:46当一个类有自己特有的“逻辑相等”概念(不同于对象身份的概念)。 2、为什么改写equals()的时候,总是要改写hashCode() 两个原则: hashCode()的返回值和equals()的关系如下: 如果x.equals(y)... -
一文搞懂hashCode()和equals()方法的原理
2021-03-12 19:49:13public boolean equals(Object obj)public int hashCode()这两个方法最开发者来说是十分重要的,必须清楚的理解,但实际上,甚至很多经验丰富的Java开发者有时候也没有真正搞清楚这两个方法的使用和原理。... -
Java面试——HashCode的作用原理和实例解析
2021-03-02 21:04:08(1)HashCode的存在主要是用于查找的快捷性,如Hashtable,HashMap等,HashCode经常用于确定对象的存储地址; (2)如果两个对象相同, equals方法一定返回true,并且这两个对象的HashCode一定相同; (3)两个... -
HashCode重写原理
2018-05-21 15:49:00例如对象 String str1 = “aa”, str1.hashCode= 3104String str2 = “bb”, str2.hashCode= 3106String str3 = “aa”, str3.hashCode= 3104根据HashCode由此可得出str1!=str2,str1==str3下面给出几个常用的哈希码... -
Java中的hashCode的计算方法与原理
2020-05-03 17:08:13在Java中,每个对象都有一个从Object基类派生出的 hashCode() 方法,用于根据当前对象的某些特征返回一个整型变量。其核心源代码中有个奇怪的数字31,本文就计算公式和取这个数字的含义进行详细的说明。 -
HashMap实现原理分析(面试问题:两个hashcode相同 的对象怎么存入hashmap的)
2020-12-31 12:20:13如果发生了碰撞,也就是说有两个对象的key 的hashcode值相等,那么则需要通过key的equals方法判断这两个对象是否是同一个对象,如果是,那么原本存 储的旧值会被新值所替换;如果不是同一个对象,则把新的键值对对象... -
GC时对象地址变了,hashCode如何保持不变?
2021-04-07 22:21:44同时我们也知道,无论何时调用同一对象的hashCode方法,都必须返回相同的值,也就是说一个对象的hashCode值要在生命周期中保持不变。同时,网传“hashCode是根据对象地址生成的”。那么,问题来了,当对象地址变化了... -
JAVA为什么两个不同对象的hashCode有可能相同
2021-03-12 21:32:43hashCode:hashCode是jdk根据对象的地址或者字符串或者数字算出来的int类型的数值。public int hashCode()返回该对象的哈希码值。支持此方法是为了提高哈希表(例如 java.util.Hashtable 提供的哈希表)的性能。理解:... -
Java String类的hashCode()和equals()原理
2022-05-09 09:12:53由于String类对hashCode()和equals(Object)方法进行了重写而String类又是一个被final修饰的类,所以无法继承该类进行进一步的自定义功能开发,因此了解其内部工作的原理是十分必要的。 -
Java课堂篇10_hash集合的一些小细节(hash冲突、集合删除元素的原理、hashCode属性、集合存放的对象增删...
2020-12-11 14:32:46写在前面 除了需要掌握集合的基本使用,还需要对Java底层了解的深一点,对我们用好这门语言更有利。...集合存放的对象增删操作需要设计重写hashCode ,否则导致元素删除失败 开始 一、hashCode属性 ... -
HashCode的作用原理和实例解析
2020-07-08 12:06:07(1)HashCode的存在主要是用于查找的快捷性,如Hashtable,HashMap等,HashCode经常用于确定对象的存储地址; (2)如果两个对象相同, equals方法一定返回true,并且这两个对象的HashCode一定相同; (3)两个... -
Java中的HashCode 1 之hash算法基本原理
2018-11-09 10:17:04Java中的HashCode 1 之hash算法基本原理 -
hashcode原理 / 比较器 / 聚合操作
2021-05-14 11:36:30目录hashcode原理比较器ComparatorComparable聚合操作 hashcode原理 List的查找效率低下 HashMap的查找效率好,几乎不花时间。类似平时查字典,先找目录找到多少页,然后直接翻到对应的页码就好了,而这个页码... -
如果两个对象不相同,他们的hashcode可能相同?
2018-01-29 22:54:38HashSet和HashMap一直都是JDK中最常用的两个类,HashSet要求不能存储相同的对象,HashMap要求不能存储相同的键。 那么Java运行时环境是...在研究这个问题之前,首先说明一下JDK对equals(Object obj)和hashcode()这 -
两个对象不相同,hashcode可能相同
2018-06-11 15:17:46HashSet和HashMap一直都是JDK中最常用的两个类,HashSet要求不能存储相同的对象,HashMap要求不能存储相同的键。... 在研究这个问题之前,首先说明一下JDK对equals(Object obj)和hashcode()这两个方法的定... -
为什么HashCode对于对象如此的重要
2018-12-06 14:16:52Hash表数据结构常识: 哈希表基于数组。 缺点:基于数组的,数组创建后难以扩展。某些哈希表被基本填满时,性能下降得非常严重。...一个对象的HashCode就是一个简单的Hash算法的实现,虽然它和那... -
hash算法的实现原理,hashcode的实现原理
2017-10-07 14:04:352 如果两个对象的hashCode相同,它们并不一定相同,这里的对象相同指的是用eqauls方法比较。 三、例子 1 没有重写hashCode和equals的方法 package cn.xy.test; ... -
hashCode和内存地址关系以及hashCode去重复原理
2021-07-26 11:02:19hashCode和内存地址关系 1.当我们没有重写hashCode方法的时候默认的哈希值是内存地址是永远不相同的 Student s=new Student(); Student a=new Student(); System.out.println(s.hashCode());//2018699554 System... -
HashSet储存对象时重写equals和hashcode方法时的情景分析
2021-01-31 18:16:53HashSet储存对象时重写equals和hashcode方法时的情景分析Set 接口的特点:hashCode() 与 equals()两种情形情形一示例:情形二示例:总结 Set 接口的特点: 1.它不允许出现重复元素-----------无重复 2.不保证...