【问题标题】:HashTable Java... Can you check my codeHashTable Java...你能检查我的代码吗
【发布时间】:2009-05-02 03:11:22
【问题描述】:

我正在为 java 中的哈希表编写一个类...你能确保我到目前为止做得正确吗?

我需要在其中存储 StudentRecord 对象....我正在根据 long 类型的学生 ID 计算哈希值...

package proj3;

import java.util.LinkedList;

public class HashTable {

    LinkedList<StudentRecord> [] buckets;
    int size;

    public HashTable(){
            size = 10;
            initialize();       
    }

    public HashTable(int initialSize){
        size = initialSize;
        initialize();
    }

    private void initialize(){
        for(int i=0; i<size; i++){
            buckets[i] = new LinkedList<StudentRecord>();
        }
    }
    /** for testing only
    private int calculateHashString(String s){
        int hash = 0;
        for(int i=0; i<s.length(); i++){
            hash += s.charAt(i);
        }
        return hash % size;
    }
    **/

    private int calculateHash(long l){
        return (int) (l % size);
    }


    public boolean contains(StudentRecord sr){
        int hash = calculateHash(sr.studentID);
        LinkedList<StudentRecord> l = buckets[hash];
        if(l.contains(sr)){
            return true;
        }
        return false;
    }

    public void put(StudentRecord sr){
        int hash = calculateHash(sr.studentID);
        LinkedList<StudentRecord> l = buckets[hash];
        if(!l.contains(sr)){
            buckets[hash].add(sr);
        }
    }

}

【问题讨论】:

  • 这是作业吗?如果是这样,你应该这样标记这个问题。
  • 在 java 中,有一个 [contract][1] 包括 .equals(Object) 和 .hashCode() 方法,允许您实现独立于键类型的哈希表。 [1]:java.sun.com/j2se/1.4.2/docs/api/java/lang/Object.html

标签: java hashtable


【解决方案1】:

我认为您可能想要编写单元测试来验证其实际功能,而与您的 f(r)iendly SO 专家是否健全地检查它无关。

除了简单的测试用例之外,还有一个好处是将您的实现功能与标准 JDK HashMap 进行比较;生成随机键和/或值,插入、删除并检查两个实现之间的状态是否相同(达到应有的程度)。

【讨论】:

    【解决方案2】:

    buckets 似乎永远不会被初始化。当你尝试这样做时,编译器应该给你一个警告。坚持使用集合而不是数组(基元除外)。

    您的无参数构造函数可以通过调用另一个构造函数 (this(10) 来更简单地实现。

    表达式(int) (l % size) 可以返回一个否定的,即使是一个肯定的size,原因不止一个。

    代码

    public boolean contains(StudentRecord sr){
        ...
        if(l.contains(sr)){
                return true;
        }
        return false;
    }
    

    可以更清楚地写成

    public boolean contains(Student student) {
        ...
        return list.contains(student);
    }
    

    【讨论】:

      【解决方案3】:

      看起来不错。

      【讨论】:

        【解决方案4】:

        Tom 是对的,您需要将存储桶初始化为新的 LinkedList[size]。

        我认为您希望最终确定尺寸,并从更大的值开始,例如 256。如果您在将项目添加到表格后调整尺寸,则需要将它们全部移动到新的存储桶中(从更改的哈希算法)。

        另一方面,10 有利于测试 - 同一个存储桶上有很多碰撞!

        为了节省内存,您不必在开始时初始化所有这些新的 LinkedList(),您可以将它们保留为 null。您可以等待创建每个列表对象,直到新项目实际命中空存储桶。当然,这将意味着需要额外的代码来检查您尝试读取的存储桶是否为空,如果是,则假定它是一个空列表。

        【讨论】:

          【解决方案5】:

          你也必须重写 equals 和 hashCode 方法。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2017-04-08
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-03-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多