如何在同一类中调用hashrealCode方法并将其返回值存入哈希表数组?
搞定基于数组的哈希表实现的那些坑
嘿,看你在实现数组版哈希表的时候踩了几个典型的Java语法和逻辑坑,我来一步步帮你梳理并修正这些问题:
先把你提到的核心问题逐个拆解
- 构造方法命名错了:Java里构造方法必须和类名完全一致(大小写都得对上),要是写错名字,那它就变成普通方法了,根本没法正确初始化你的哈希表对象。
- 类型不匹配是逻辑误解:你的Employee数组是用来存员工对象的,哈希值(int类型)是用来算这个对象该存在数组的哪个位置(索引),不是直接把哈希值塞数组里啊!
- 方法调用的小问题:如果
hashrealCode是HashTableEmployee的实例方法,在addTheEmployee里直接调用hashrealCode(e)就行(或者加个this.明确指当前实例,不过没必要),只有静态方法才需要用类名调用。
先理清楚哈希表的核心逻辑
数组哈希表的本质是:
- 用哈希函数(就是你的
hashrealCode)把Employee对象转成int值,再通过取模运算映射到数组的合法索引。 - 数组的每个位置是个"桶",用来装哈希值相同的对象(处理哈希冲突,这里用最简单的链表当桶,好扩展)。
- 添加对象时,先算索引,再把对象丢到对应桶里。
修正后的完整代码示例
1. 先把Employee类弄对(确保hashCode和equals重写正确)
public class Employee { private int id; private String name; public Employee(int id, String name) { this.id = id; this.name = name; } // 重写hashCode,这里用id生成哈希值,你可以根据需求加name之类的字段 @Override public int hashCode() { return Integer.hashCode(id); } // 必须重写equals,不然哈希表没法判断两个对象是不是同一个 @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null || getClass() != obj.getClass()) return false; Employee employee = (Employee) obj; return id == employee.id; } // Getters方便调试和查找 public int getId() { return id; } public String getName() { return name; } @Override public String toString() { return "Employee{id=" + id + ", name='" + name + "'}"; } }
2. 修正后的HashTableEmployee类
import java.util.LinkedList; public class HashTableEmployee { // 哈希表的桶数组,每个桶是Employee的链表,用来处理哈希冲突 private LinkedList<Employee>[] hashTable; private int capacity; // 数组的容量 // 构造方法:必须和类名完全一致,初始化每个桶 public HashTableEmployee(int capacity) { this.capacity = capacity; // 初始化数组,每个位置新建一个空链表 hashTable = new LinkedList[capacity]; for (int i = 0; i < capacity; i++) { hashTable[i] = new LinkedList<>(); } } // 自定义哈希函数:把Employee的hashCode转成合法的数组索引 private int hashrealCode(Employee e) { // 取绝对值避免负数索引,再对容量取模得到0到capacity-1的索引 return Math.abs(e.hashCode()) % capacity; } // 添加员工的核心方法 public void addTheEmployee(Employee e) { if (e == null) { throw new IllegalArgumentException("员工对象不能为null"); } // 1. 计算当前员工对应的桶索引 int bucketIndex = hashrealCode(e); // 2. 检查桶里有没有重复的员工(避免重复添加) if (!hashTable[bucketIndex].contains(e)) { // 3. 把员工加到对应桶的链表中 hashTable[bucketIndex].add(e); System.out.println("已添加员工: " + e + " 到桶 " + bucketIndex); } else { System.out.println("员工 " + e + " 已经在哈希表里了"); } } // 可选:根据id查找员工的方法,验证哈希表功能 public Employee findEmployee(int id) { // 造个临时对象用来算哈希值和比较 Employee temp = new Employee(id, ""); int bucketIndex = hashrealCode(temp); // 遍历对应桶的链表找目标员工 for (Employee employee : hashTable[bucketIndex]) { if (employee.getId() == id) { return employee; } } return null; // 没找到返回null } // 测试用的main方法,跑一下看看效果 public static void main(String[] args) { HashTableEmployee ht = new HashTableEmployee(10); ht.addTheEmployee(new Employee(1, "Alice")); ht.addTheEmployee(new Employee(11, "Bob")); // 11%10=1,和id=1的桶相同,测试冲突处理 ht.addTheEmployee(new Employee(1, "Alice")); // 测试重复添加 Employee found = ht.findEmployee(11); System.out.println("找到员工: " + found); } }
关键修正点再强调下
- 构造方法:现在名字和类名完全一致了,能正确初始化哈希表的桶数组。
- 数组类型:把原来的
Employee[]换成LinkedList<Employee>[],每个桶是链表,完美处理多个对象哈希到同一个索引的冲突情况。 - 哈希值的用法:
hashrealCode返回的是数组索引,我们用这个索引找到对应的桶,再把Employee对象存进桶的链表,而不是把哈希值存数组里。 - 方法调用:在
addTheEmployee里直接调用hashrealCode(e)就行,因为它是当前类的实例方法,语法完全正确。
你可以根据自己的需求调整哈希函数的实现(比如结合name字段生成更均匀的哈希值),或者把桶的实现换成数组(不过链表更适合动态添加的场景)。
内容的提问来源于stack exchange,提问作者jeryoz dimitar
相关产品推荐
相关产品推荐

