使用链式对象的

时间:2015-05-03 08:03:00

标签: java hash linked-list hashtable hashcode

我有这个实现插入到使用顺序链接的哈希表中:

public void insert(String word, Definition definition) {

       int hash = hashFunction(word);


        if (table[hash] == null) {           
            EntryImplSub chainedEntry = new EntryImplSub(null);
            chainedEntry.addDefinition(definition);
            chainedEntry.setWord(word);

            table[hash] = chainedEntry;
            numProbes++;
            entries++;

        } 

        else{

            EntryImplSub chainedEntry = new EntryImplSub(table[hash]);
            chainedEntry.addDefinition(definition);
            chainedEntry.setWord(word);

            table[hash] = chainedEntry;
            numProbes++;
            }

      }

基本上,我正在尝试制作一本字典。有一个EntryImpl类充当入口对象,每个条目都有一个单词和定义(或多个定义)。现在我已经创建了一个新的扩展类EntryImplSub,它意味着被链接。这个新类有一个getNext()方法,并继承了普通EntryImpl类的所有其他功能。 EntryImplSub构造函数用于设置next。

问题

然而这不起作用。当我加载大量单词时,它们并非都被输入。我不确定为什么。

我的尝试

我对这个实现的逻辑是,如果表项为null,我们插入一个新的EntryImplSub对象,其中next = null,然后设置单词和定义。

但是,如果我们尝试插入的位置已经有一个单词,那么我们必须将新条目添加到列表的前面。因此,我们创建一个新的EntryImplSub对象,其下一个属性设置为表中已有的内容。然后我为新的EntryImplSub设置单词并将其插入表中。所以我们应该有一个EntryImplSub链接列表。

我真的不确定为什么这个工作正常。我花了好几个小时试图找到错误,任何帮助将不胜感激。如果您需要澄清任何事情,请告诉我。

非常感谢!

修改

以下是检查条目是否在表格中的代码

 public List<Definition> getDefinitions(String word) {

    int hash = hashFunction(word);
    //ChainedEntry head = table[hash];
    while (table[hash] != null) {
        numSearches++;

        if (((EntryImpl) table[hash]).getWord().equals(word)) {
            return ((EntryImpl) table[hash]).getDefinitions();
        }
        table[hash] = table[hash].getNext();
    }

    return null;
}

如果返回null,则该字不在表

2 个答案:

答案 0 :(得分:1)

我会像这样简化代码并编写一个简短的单元测试。最有可能的是,这将需要2-3个条目来重现问题,而这个问题最有可能出现在您尚未展示的代码中。

public void insert(String word, Definition definition) {
   int hash = 0; // put everything in one bucket for now // hashFunction(word);

    if (table[hash] == null) 
        entries++;        

    EntryImplSub chainedEntry = new EntryImplSub(table[hash]);
    chainedEntry.addDefinition(definition);
    chainedEntry.setWord(word);

    table[hash] = chainedEntry;
    numProbes++;
}

由于word无法更改,我会将其作为构造函数参数(以及final字段)

答案 1 :(得分:1)

查找定义的代码不正确:它修改了哈希表的结构:

table[hash] = table[hash].getNext();

这将替换下一个条目中的条目,从而有效地从地图中删除先前的条目。

由于您的插入代码只会在条目中添加一个定义,并且由于可以在地图中多次添加相同的单词,因此代码应该看起来像

int hash = hashFunction(word);
List<Definition> result = new ArrayList<>();
EntryImpl entry = table[hash];
while (entry != null) {
    if (entry.getWord().equals(word)) {
        result.addAll(entry.getDefinitions());
    }
    entry = entry.getNext();
}
return result;