Вопрос по java – hashCode () для массива объектов для использования в HashMap

1

У меня есть следующие два класса, и я хочу использоватьFoo1 в качестве ключей вHashMap, ДваFoo1 объекты равны, если ихFoo2 объекты равны, иFoo2 объекты равны, если их байтовые массивы удовлетворяютArrays.equals().

Я не совсем уверен, что делать дляhashCode() метод дляFoo1, Нужно ли просто суммировать хеш-коды от каждого изFoo2 объекты или это неэффективно?

public class Foo1 {

  Foo2[] foo2_array;

  @Override
  public boolean equals(Object Other) {

     for (int i = 0; i < foo2_array.length; i++) {

        if (!foo2_array[i].equals(other.foo2_array[i])
          return false;
     }

     return true;
   }

   @Override
   public int hashCode() {

      // what to here?
   }
}

public class Foo2 {

  byte[] values;

  @Override
  public boolean equals(Object other) {

      return Arrays.equals(values, other.values);
  }

  @Override
  public int hashCode() {

     return Arrays.hashCode(values);
  }
}
Чем ваша логика Foo1 отличается от логики Foo2? В обоих случаях вы хотите, чтобы поля массива каждого объекта были равны по компонентам. Почему бы не использовать Arrays.equals / Arrays.hashCode в обоих случаях? (Кстати, Foo2 никак не будет компилироваться как есть без приведения) Judge Mental

Ваш Ответ

2   ответа
4

Вашhashcode следует использовать тот же набор свойств, что иequals чтобы это не нарушало договор.

Просто используйтеArrays.hashcode как сделано вFoo2

Кроме того, вам не нужно перебирать каждый элемент в ваших равных, вы можете просто использоватьArrays.equals

Foo2 equals может выглядеть примерно так же, как Foo1.equals

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Foo1 other = (Foo1) obj;
        if (!Arrays.equals(foo2_array, other.foo2_array))
            return false;
        return true;
    }

и хэш-код, похожий на хэш-код Foo1

    @Override
    public int hashCode() {
        return Arrays.hashCode(foo2_array);
    }

Также при реализации equals проверяют одинаковую ссылку и валидность объекта для null.

0

По сути, вам нужен какой-то метод, который делает вероятным, что разные объекты будут иметь разные хеш-коды.

Таким образом, в зависимости от ваших данных, вы не обязательноneed суммировать хешall элементы в массиве. Вам просто нужно что-то "достаточно хорошее, чтобы сузить круг".

Я бы сказал так: есть ли что-то в ваших данных, что заставляет вас подозревать, что вы не можете просто взять, скажем, хеш-код среднего значения массива? Или, например, комбинированные хеш-коды первого, последнего и среднего элементов, например?

(Вещи, которые могут заставить вас подозревать, что вы не можете этого сделать: если, скажем, ваши данные имели какую-то особую функцию, благодаря которой определенное узкое подмножество значений появляется в качестве среднего элемента в массиве.)

Похожие вопросы