原作者:http://blog.csdn.net/woshixuye/article/details/8189398
一、为什么要有Hash算法
Java中的集合有两类,一类是List,一类是Set。List内的元素是有序的,元素可以重复。Set元素无序,但元素不可重复。要想保证元素不重复,两个元素是否重复应该依据什么来判断呢?用Object.equals方法。但若每增加一个元素就检查一次,那么当元素很多时,后添加到集合中的元素比较的次数就非常多了。也就是说若集合中已有1000个元素,那么第1001个元素加入集合时,它就要调用1000次equals方法。这显然会大大降低效率。于是Java采用了哈希表的原理。哈希(Hash)是个人名,由于他提出哈希算法的概念就以他的名字命名了。
二、Hash算法原理
当Set接收一个元素时根据该对象的内存地址算出hashCode,看它属于哪一个区间,在这个区间里调用equeals方法。
确实提高了效率。但一个面临问题:若两个对象equals相等,但不在一个区间,根本没有机会进行比较,会被认为是不同的对象。所以Java对于eqauls方法和hashCode方法是这样规定的:
1 如果两个对象相同,那么它们的hashCode值一定要相同。也告诉我们重写equals方法,一定要重写hashCode方法。
2 如果两个对象的hashCode相同,它们并不一定相同,这里的对象相同指的是用eqauls方法比较。
三、例子
1 没有重写hashCode和equals的方法
package cn.xy.test;
public class Point1
{
private int x;
private int y;
public Point1(int x, int y)
{
super();
this.x = x;
this.y = y;
}
public int getX()
{
return x;
}
public void setX(int x)
{
this.x = x;
}
public int getY()
{
return y;
}
public void setY(int y)
{
this.y = y;
}
}
public class HashSetAndHashCode
{
public static void main(String[] args)
{
HashSet<Point1> hs1 = new HashSet<Point1>();
Point1 p11 = new Point1(3, 3);
Point1 p12 = new Point1(3, 3);
Point1 p13 = new Point1(3, 5);
hs1.add(p11);
hs1.add(p11);
hs1.add(p12);
hs1.add(p13);
System.out.println(hs1.size());
}
}
答案是3
2 重写hashCode和equals的方法
package cn.xy.test;
public class Point2
{
private int x;
private int y;
public Point2(int x, int y)
{
super();
this.x = x;
this.y = y;
}
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + x;
result = prime * result + y;
return result;
}
@Override
public boolean equals(Object obj)
{
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
Point2 other = (Point2) obj;
if (x != other.x) return false;
if (y != other.y) return false;
return true;
}
public int getX()
{
return x;
}
public void setX(int x)
{
this.x = x;
}
public int getY()
{
return y;
}
public void setY(int y)
{
this.y = y;
}
}
public class HashSetAndHashCode
{
public static void main(String[] args)
{
HashSet<Point2> hs2 = new HashSet<Point2>();
Point2 p21 = new Point2(3, 3);
Point2 p22 = new Point2(3, 3);
Point2 p23 = new Point2(3, 5);
hs2.add(p21);
hs2.add(p22);
hs2.add(p23);
System.out.println(hs2.size());
}
}
答案是2。p21和p22被认为是同一个对象。
3 没有重写hashCode的方法,但重写equals的方法
package cn.xy.test;
public class Point3
{
private int x;
private int y;
public Point3(int x, int y)
{
super();
this.x = x;
this.y = y;
}
@Override
public boolean equals(Object obj)
{
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
Point3 other = (Point3) obj;
if (x != other.x) return false;
if (y != other.y) return false;
return true;
}
public int getX()
{
return x;
}
public void setX(int x)
{
this.x = x;
}
public int getY()
{
return y;
}
public void setY(int y)
{
this.y = y;
}
}
public class HashSetAndHashCode
{
public static void main(String[] args)
{
HashSet<Point3> hs3 = new HashSet<Point3>();
Point3 p31 = new Point3(3, 3);
Point3 p32 = new Point3(3, 3);
Point3 p33 = new Point3(3, 5);
hs3.add(p31);
hs3.add(p32);
hs3.add(p33);
System.out.println(hs3.size());
}
}
可能是2,可能是3。因为根据内存地址算出的hashcode不知道是否在一个区域。
相关推荐
在 Java 中,默认的 Hash Code 计算算法是基于字符串的内容进行计算的。该算法将字符串的每个字符的 ASCII 码值相加,得到一个整数值作为 Hash Code。 然而,这种算法存在缺陷。如果两个字符串的 ASCII 码值相加...
"java中的哈希算法和hashcode深入讲解" 哈希算法是计算机领域中非常重要的一种技术,它具有非常广泛的应用,例如快速查找和加密。哈希算法可以将任意长度的二进制值映射为较短的、固定长度的二进制值,这个二进制值...
了解了`hashCodeUtil`的基本原理后,我们可以将其应用到实际项目中,优化自定义类的`hashCode()`方法,提升数据结构如HashMap的性能。同时,我们也应该注意,虽然好的哈希函数可以降低碰撞,但完全避免碰撞是不可能...
在java中一个hashCode算法,可以用来计算一个字符串的hash值,今天一个朋友突然问俺能不能在js中计算hashCode,要求和java的hashCode计算结果一样。 对于java的hashCode,以前到现在也一直没有了解过其算法,不过...
### Java中`hashCode()`与`equals()`方法详解 #### 前言 在Java编程语言中,`hashCode()`和`equals()`方法是非常重要的概念,它们主要用于处理对象的唯一标识和对象之间的相等性判断。正确地实现这两个方法对于确保...
在Java编程语言中,`hashCode()` 和 `equals()` 是两个非常重要的方法,它们主要用于对象的比较和哈希表(如HashMap)的操作。标题提到的"HashCode相同equals不同的2位字符集合算法"涉及到的是一个特定场景:两个...
下面我们将深入探讨一致性哈希算法的原理、特点以及Java实现。 一致性哈希算法的核心思想是将数据和服务器都映射到一个固定大小的哈希环上,数据根据其哈希值被分配到最近的服务器节点。当新增或移除服务器时,只有...
在Java中,所有对象都有hashCode()方法,这个方法返回对象的一个整数值,作为其散列码。这个散列码用于在基于散列的集合(如HashSet、HashMap、HashTable)中定位对象。当向这些集合中添加对象时,首先调用hashCode...
在前面三篇博文中LZ讲解了(HashMap、HashSet、HashTable),在其中LZ不断地讲解他们的put和get方法,在这两个方法中计算key的hashCode应该是重要也是精华的部分,所以下面LZ揭开hashCode的“神秘”面纱。...
哈希码(Hash Code)是一种在计算机科学中广泛使用的数据处理技术,主要应用于查找和存储。标题中的"hash code"指的是这种技术,...在Java编程中,掌握`hashCode()`的使用和重写规则,是成为合格开发者的重要技能之一。
1. Java中实现MD5加密算法需要使用java.security包中的MessageDigest类。 2. MD5加密算法是一种不可逆的加密算法,破解的难度很高。 3. 使用Singleton模式可以实现MD5加密算法的实例。 4. 在Java中可以使用update...
首先,`e.hash`是HashMap中某个元素的哈希值,它由键对象的`hashCode()`方法计算得出,通常是键对象的哈希码右移16位后再与原始哈希码异或得到。`oldCap`是旧数组(即当前HashMap的容量)的长度,由于HashMap的容量...
这个"java-hash.7z"压缩包包含了一个Java实现的哈希计算工具,这是一份经典的学习资源,可以帮助开发者深入理解哈希算法及其在Java中的应用。 哈希(Hash)函数是一种将任意长度输入(也叫做预映射pre-image)通过...
在Java中,可以使用`Objects.hash()`方法生成哈希码,这是一个优化过的算法,减少了冲突的可能性。 3. 哈希码的复用:在某些特定场景下,我们可以考虑重用已有的哈希码,以减少计算开销。例如,如果对象在生命周期...
本资源详细介绍了 Java 中的 HashMap 类,包括其实现机制、Hash 存储机制、集合存储机制等方面的知识点。 1. HashMap 和 HashSet 的关系 HashMap 和 HashSet 是 Java Collection Framework 的两个重要成员,虽然...
本文将重点解析`HashMap`中hash算法的核心原理及其优化细节。 #### 二、计算Key的HashCode `HashMap`在存储数据时首先需要计算出每个键(key)对应的哈希码(hashCode)。这个过程通常通过调用对象自身的`hashCode...
1. **默认实现**:每个Java对象都有一个默认的 `hashCode` 实现,该实现是基于对象在内存中的地址计算得出的。 2. **自定义实现**:在某些情况下,需要根据对象的状态来自定义 `hashCode` 方法,这通常涉及到对象中...
负载均衡算法及Java实现 负载均衡是指通过某种负载分担技术,将外部发送来的请求均匀分配到对称结构中的某一台服务器上,以解决大量并发访问服务问题。负载均衡能够平均分配客户请求到服务器阵列,借此提供快速获取...
在Java中,所有的对象都继承自Object类,而Object类中提供了一个默认的hashCode()方法,该方法通常基于对象的内存地址来计算哈希码。为了确保两个相等的对象在哈希表中可以被正确地映射到相同的“桶”(bucket)里,...