任何Java对象都有一个继承自Object类的hashcode()方法用来返回这个对象对应的散列值。
散列值最常见的使用是会被用来在散列表中查找索引值的用到。
不同索引值在节点会处在不同的散列表的不同节点上;相同散列值的节点以一个单向链表相连。
查找过程大致如下:
int hashcode = key.hashCode();
int index = (hashcode & 0x7FFFFFFF) % hashMap.length;
for(Entry e = hashMap[index]; e != null ; e = e.next){
if((e.hashCode()==hashcode) && key.equals(e.key))
return e.value;
}
return null;
从中可以看到,如果散列值和键都相等,则键对应的值就会被返回。如果我们有一个自定义的类,类的hashCode()方法和equals()方法设计的不好,可能会有不期望的结果返回,例如我们有一个以下的类:
public class Personal {
private int age;
private String name;
private String national;
public Personal(int age, String name, String national) {
super();
this.age = age;
this.name = name;
this.national = national;
}
public int hashCode() {
return age | name.hashCode();
}
public int getAge() {
return age;
}
public String getName() {
return name;
}
public String getNational() {
return national;
}
public boolean equals(Object obj) {
if(this == obj) return true;
if (obj instanceof Personal) {
return age == ((Personal) obj).age
&& name.equals(((Personal) obj).name);
}
return false;
}
}
有以下测试类:
public class HashcodeTest {
public static void main(String[] args) {
Map<Personal, String> map = new HashMap<Personal, String>();
Personal model1 = new Personal(32, "name", "China");
Personal model2 = new Personal(32, "name", "USA");
map.put(model2, "USA");
map.put(model1, "China");
System.out.println(map.get(model2));
System.out.println(map.get(model1));
}
}
我这里看到运行结果为:
China
China
我们期望的是:
USA
China
之所以会出现这种情况,就是因为我们的hashCode()和equals()方法设计的不好,只考虑了age和name的信息。如果把national的信息也加上,这个问题就容易解决了。可以修改hashCode()方法加上national.hashCode(),也可以修改equals()方法,加上national的信息;或者两者都修改。不过建议在hashCode()方法和equals()方法里使用的变量保持一致或是其子集
分享到:
相关推荐
就是java的散列表示意图 很清晰易懂 比枯燥额文字好多了
为了实现电话号码的添加,我们需要创建一个`HashMap`对象,然后将每个姓名或身份证号作为键,对应的电话号码作为值插入到散列表中。例如: ```java HashMap, String> phoneBook = new HashMap(); phoneBook.put(...
* 基于散列表实现的(无序)词典结构 * 采用分离链策略解决冲突 */ package dsa; public class Dictionary_HashTable implements Dictionary { private Dictionary[] A;//桶数组,每个桶本身也是一个(基于...
1. **添加联系人**:用户输入姓名和电话号码后,应用应将这对信息插入到散列表中。这涉及到调用`HashMap`的`put()`方法。 2. **查找联系人**:用户输入姓名后,系统应返回对应的电话号码。这可以通过调用`HashMap`...
Java集合框架-添加了散列表
在散列表中,当我们插入一个键值对时,首先计算键的散列值,然后将该值作为数组的索引。如果这个位置已经有其他元素,我们就把新的键值对添加到该位置链表的末尾。这样,即使散列函数导致多对键值对映射到同一位置,...
5. **负载因子**:负载因子是散列表中已存元素数量与总容量的比值,它是影响查询效率的重要因素。为了保持良好的性能,系统需要适时地调整散列表大小,以维持合适的负载因子。 6. **动态扩容**:随着电话号码的增加...
电话号码查找系统是一种高效的数据检索方法,通过散列表来实现,可以快速定位和显示特定电话号码或用户名对应的记录。在本课程设计中,学生李激光使用Visual C++编程语言,结合MS SQL 2000数据库,构建了一个能在...
在Java中,散列表的实现通常是基于数组和链表的组合,以处理可能出现的键冲突问题。 散列函数是散列表的核心,它负责将任意键转换为数组的索引。理想的散列函数应该使不同的键得到不同的索引,但在实际应用中,由于...
Java中的散列表,也称哈希表,是一种高效的数据结构,它通过散列函数将关键字(key-value)直接映射到存储结构中的特定位置,从而实现了快速查找。散列表的关键在于散列函数,这个函数能够将任何类型的键转化为数组...
散列表(HashMap)是一种在计算机科学中广泛使用的数据结构,它的主要目的是提供快速的数据存取。散列表通过将键(Key)映射到一个索引来实现这一目标,这个索引通常是一个整数值,对应存储值的位置。散列表的运作...
这样,即使散列表中元素的位置因哈希冲突而混乱,仍能通过链表按添加顺序访问元素,同时保持O(1)的查找效率。 总的来说,散列表通过巧妙地结合数组和哈希函数,实现了高效的动态数据存储。通过处理哈希冲突和适时扩...
关于分布式散列表DHT的前世今生的故事:包括单机hash、分布式一致性hash
- **散列表(Hash Table)**:`java.util.HashMap`和`java.util.HashSet`分别提供了散列表的实现。 此外,还可以使用Java语言特性,如递归、循环等来实现各种算法。 ### 结论 掌握数据结构与算法不仅能够帮助开发者...
设计散列表实现电话号码查找系统。 [基本要求] [需求分析] (1)设每个记录有下列数据项: 电话号码、用户名、地址; (2)从键盘输入各记录,分别以电话号码和用户名为关键字建立散列表; (3)采用一定的方法解决冲突...
Java的HashMap和TreeMap类实现了散列表,前者基于开放寻址,后者则保证了元素的排序。 7. **树**:树是一种非线性数据结构,包括二叉树、平衡二叉树(如AVL树和红黑树)以及B树等。它们在搜索、排序和文件系统中...
Java中的HashMap类和HashSet类是散列表的常见应用。 在"数据结构—Java语言描述"课程中,你将学习到如何在Java中实现这些数据结构,以及它们的特性、操作方法和适用场景。同时,源代码部分会提供实际的示例,帮助你...
HashMap类使用散列表来存储键值对,查找和操作的效率非常高。HashMap类是线程非同步的(asynchronized),因此在多线程环境下需要小心使用。 SortedMap接口 SortedMap接口继承自Map接口,是一个有序的Map接口。...
Java中利用散列表实现股票行情的查询 Java中文问题详解 Vector在Java编程中的应用 编写高级应用程序1 编写高级应用程序2 实现 Swing 的 JTables 和 Excel 间的复制和粘贴功能 实 现JAVA 的 动 态 类 载 入 机 ...