java 如何为特定类编写 hashCode 方法?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16377926/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 22:48:29  来源:igfitidea点击:

How to write hashCode method for a particular class?

javaclasscharacterhashcodecompareto

提问by A Gore

I'm trying to generate a hashCode() method for my simple class but i'm not getting anywhere with it. I would appreciate any help. I've implemented the equals() method, which looks as follows, and would also like to know if I need to implement compareTo() method. I've imported java.lang.Character to use character.hashCode() but it doesn't seem to work.

我正在尝试为我的简单类生成一个 hashCode() 方法,但我没有得到任何结果。我将不胜感激任何帮助。我已经实现了equals()方法,如下所示,还想知道是否需要实现compareTo()方法。我已经导入 java.lang.Character 来使用 character.hashCode() 但它似乎不起作用。

private class Coord{
    private char row;
    private char col;
    public Coord(char x, char y){
        row = x;
        col = y;
    }
    public Coord(){};

    public char getX(){
        return row;
    }

    public char getY(){
        return col;
    }

    public boolean equals(Object copy){
        if(copy == null){
            throw new NullPointerException("Object entered is empty");
        }
        else if(copy.getClass()!=this.getClass()){
            throw new IllegalArgumentException("Object entered is not Coord");
        }
        else{
            Coord copy2 = (Coord)copy;
            if(copy2.row==this.row && copy2.col==this.col)
                return true;
            else
                return false;
        }
    }

}

Thanks in advance...

提前致谢...

The comparTo() method that is giving me java.lang.Comparable casting error..

给我 java.lang.Comparable 转换错误的 comparTo() 方法..

public int compareTo(Object copy){
        if(copy==null){
            throw new NullPointerException("Object entered is empty");
        }
        else if(copy.getClass()!=this.getClass()){
            throw new IllegalArgumentException("Object entered is not Coord");
        }
        else{
            Coord copy2 = (Coord)copy;
            if(copy2.row==this.row && copy2.col==this.col){
                return 0;
            }
            else if(copy2.col < this.col){
                return -1;
            }
            else{
                return 1;
            }
        }
    }

thanks...

谢谢...

采纳答案by nullptr

To implement hashCode, you override the default implementation from Object:

要实现 hashCode,您需要覆盖 Object 的默认实现:

@Override
public int hashCode()
{
    return row ^ col;
}

This isn't really an ideal hash, since its results are very predictable and it is easy for two different Coordobjects to return the same value. A better hash would make use of the built-in Arraysclass from java.util(http://docs.oracle.com/javase/7/docs/api/java/util/Arrays.html):

这并不是一个理想的散列,因为它的结果是非常可预测的,而且两个不同的Coord对象很容易返回相同的值。更好的散列将使用Arrays来自java.util( http://docs.oracle.com/javase/7/docs/api/java/util/Arrays.html)的内置类:

@Override
public int hashCode()
{
    return Arrays.hashCode(new Object[]{new Character(row), new Character(col)});
}

You can use this method to generate a pretty good hash with any number of fields.

您可以使用此方法生成具有任意数量字段的非常好的散列。

To implement compareTo, you'll want your class to implement Comparable:

要实现 compareTo,你需要你的类实现Comparable

public class Coord implements Comparable<Coord>

Once you've done this, you can make compareTo take an argument of type Coordrather than type Object, which will save you the trouble of checking its type.

完成此操作后,您可以让 compareTo 接受 typeCoord而不是 type的参数Object,这样可以省去检查其类型的麻烦。

回答by durron597

Hashcode is an int(32 bits), your data is char(16 bits), so I would probably just do:

哈希码是int(32 位),您的数据是char(16 位),所以我可能会这样做:

@Override
public int hashCode() {
    return (row << 16) + col;
}

This puts the bits from rowin the first 16 bits and the bits from colin the last 16 bits, so this is a perfecthash functionfor this class.

这会将row前 16 位中的位和后 16 位中的位col放在一起,因此这是该类的完美散列函数

If you refactor your class to be more complicated, I recommend using nullptr's answer.

如果您将类重构为更复杂,我建议使用 nullptr 的答案。



To use Comparable, do:

要使用Comparable,请执行以下操作:

public class Coord implements Comparable<Coord>

回答by Matthias Herlitzius

I found very valuable information concerning this topic and many other topics in the Effective Java book, written by Joshua Bloch. Look at page 45 for further information about hashCode() and equals().

我在Joshua Bloch 所著Effective Java 一书中找到了关于这个主题和许多其他主题的非常有价值的信息。有关 hashCode() 和 equals() 的更多信息,请查看第 45 页。

If you use an IDE like Eclipse you can let it generate the hashCode()and equals()methods. For your class the result would be:

如果您使用像 Eclipse 这样的 IDE,您可以让它生成hashCode()equals()方法。对于您的班级,结果将是:

class Coord implements Comparable<Coord> {

    private char row;
    private char col;

    public Coord(char x, char y) {
        row = x;
        col = y;
    }

    public Coord() {
    };

    public char getX() {
        return row;
    }

    public char getY() {
        return col;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + col;
        result = prime * result + row;
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Coord other = (Coord) obj;
        if (col != other.col)
            return false;
        if (row != other.row)
            return false;
        return true;
    }

    public int compareTo(Coord param) {
        // Implementation according to http://docs.oracle.com/javase/7/docs/api/java/lang/Comparable.html
        return 0;
    }

}

回答by Peeyush

similar to durron597's answer, you can try this if your input is bounded by char (between 0 and 65535 )

类似于 durron597 的答案,如果您的输入受字符限制(介于 0 和 65535 之间),则可以尝试此操作

public int hashCode(){
   return row * 100000 + col;
}