哈希码返回意外结果

时间:2019-04-24 15:02:17

标签: java hashcode

我试图使用HashTable(我必须使用哈希)来存储电话目录。我想根据姓氏(字母顺序)对电话条目进行排序。我决定将条目中姓氏的第一个字符的hashCode用作HashTable的键。

这是我在Entry类中编写的hashCode:

@Override
public int hashCode() {
    int index= getSurname().charAt(0);
    return index;
}

这是用于将新条目添加到目录中的addEntry方法:

@Override
public void addEntry(Entry line) {
    //Throws an exception if either surname, initials or number are null.
    if (line.getSurname()==null||line.getInitial()==null||line.getNumber()==null){
        throw new IllegalArgumentException("Please provide a Surname, Initials and a Number");
    }

    //Throws an exception if initials are less than 2
    if (line.getInitial().length() < 2) {
        throw new IllegalArgumentException("Please make sure that initials include both first name and surname eg: AK");
    }

    //Throws an exception if the length of the number is not 5 characters.
    if (line.getNumber().length() != 5) {
        throw new IllegalArgumentException("Please provide a Number that is 5 characters long (make sure that it starts with 0)");
    }

    //Throws an exception if the number doesnt start with 0.
    if (line.getNumber().startsWith("0") == false) {
        throw new IllegalArgumentException("The Number must start with a 0");
    }

    //Initialises the key using the hashCode of surname.
    int key=line.getSurname().hashCode();

    //If statement checks if the HashTable entries contains the key
    if (entries.contains(key)){
        //If it does it creates a linkedList called list
        LinkedList<Entry> list =new LinkedList();

        list=entries.get(key);
        ListIterator<Entry> iterator = list.listIterator();

        while (iterator.hasNext()){
            int x=0;
            String one = list.get(x).getSurname();

            if (one.compareToIgnoreCase(line.getSurname()) > 0){
                entries.put(x,list);
                x++;
                break;
            }
        }
    } else {
        LinkedList<Entry> list2 =new LinkedList();
        list2.add(line);
        entries.put(key,list2);
    }
}

问题是当我做了一些测试以查看添加不同条目的结果时,我发现密钥(hashCode)生成不正确。

这些是结果:

Key: -2083437938. Value: [Entry{surname='Jansas initials=KJ Phone number=05544'}]
Key: -1911680082. Value: [Entry{surname='Paul initials=AP Phone number=05572'}]
Key: 66344. Value: [Entry{surname='Aza initials=AZ Phone number=05212'}]
Key: 867699843. Value: [Entry{surname='Penny initials=KP Phone number=05271'}]
Key: 1953849949. Value: [Entry{surname='Aanais initials=AP Phone number=05562'}]

姓“ Aza”的条目是否应该在“ Penny”上方并在“ Aanais”旁边?关于如何解决该问题的任何想法?

1 个答案:

答案 0 :(得分:2)

您写了

...
int key=line.getSurname().hashCode();
...

当我正确看到它时,line变量的类型为Entry,您将覆盖该hashCode类中的Entry。上面的片段应该是

...
int key=line.hashCode();
...

否则,您将使用类hashCode的{​​{1}}方法(或返回的任何String)。

但是,这对于Java哈希码来说不是一个很好的实现,它不是为您的用例设计的。我会重新考虑您在这里使用的排序方法。