Как написать метод hashCode для определенного класса?
Я пытаюсь создать метод 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;
}
}
}
Спасибо заранее...
Метод ComparTo(), который дает мне java.lang.Comparable ошибку кастинга.
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;
}
}
}
спасибо...
Ответы
Ответ 1
Для реализации hashCode вы переопределяете реализацию по умолчанию из Object:
@Override
public int hashCode()
{
return row ^ col;
}
Это не идеальный хеш, так как его результаты очень предсказуемы, и для двух разных объектов 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)});
}
Вы можете использовать этот метод для создания довольно хорошего хэша с любым количеством полей.
Для реализации compareTo вы хотите, чтобы ваш класс реализовал Comparable:
public class Coord implements Comparable<Coord>
Как только вы это сделаете, вы можете сделать compareTo взять аргумент типа Coord
, а не тип Object
, что избавит вас от необходимости проверять его тип.
Ответ 2
Hashcode - это int
(32 бит), ваши данные char
(16 бит), поэтому я бы просто сделал:
@Override
public int hashCode() {
return (row << 16) + col;
}
Это ставит биты из row
в первые 16 бит и бит из col
в последние 16 бит, поэтому это perfect хэш-функции для этого класса.
Если вы реорганизуете свой класс, чтобы быть более сложным, я рекомендую использовать ответ nullptr.
Чтобы использовать Comparable
, выполните:
public class Coord implements Comparable<Coord>
Ответ 3
Я нашел очень ценную информацию по этой теме и многим другим темам в Эффективной Java-книге, написанной Джошуа Блохом. Посмотрите на стр. 45 для получения дополнительной информации о hashCode() и equals().
Если вы используете IDE, например Eclipse, вы можете позволить ему генерировать методы 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;
}
}
Ответ 4
похож на ответ durron597, вы можете попробовать это, если ваш вход ограничен char (между 0 и 65535)
public int hashCode(){
return row * 100000 + col;
}