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

У меня есть следующие два класса, и я хочу использовать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);
  }
}
 Judge Mental25 мая 2012 г., 06:34
Чем ваша логика Foo1 отличается от логики Foo2? В обоих случаях вы хотите, чтобы поля массива каждого объекта были равны по компонентам. Почему бы не использовать Arrays.equals / Arrays.hashCode в обоих случаях? (Кстати, Foo2 никак не будет компилироваться как есть без приведения)

Ответы на вопрос(2)

Решение Вопроса

Ваш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.

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

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

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

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

Ваш ответ на вопрос