Поэтапно возрастающие хэш-коды в коллекции объектов - PullRequest
0 голосов
/ 16 января 2012

Привет, ребята: я пытаюсь просмотреть некоторые объекты, чтобы увидеть, есть ли повторы. Для этого я использую поле hashCode. Объекты сериализуются в двоичном файле.

Это выглядит так:

26594 = хэш-код = 26595 хэш-код = 26596 хэш-код ...

Я бы никогда не ожидал, что hashCodes из коллекции будут демонстрировать такой шаблон, если JVM или thrift не создадут hashCodes на лету для некоторых объектов, в определенных случаях (или, может быть, каждый созданный объект имеет hashCode, который установлен в статически увеличенное значение).

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

  • Незначительные детали: эти объекты бинарно сериализуются с использованием библиотеки Apache Thrift, и они полностью читаются / пишутся в java / hadoop.

Ответы [ 3 ]

1 голос
/ 17 января 2012

существует ли причина или распространенный случай, когда поток объектов будет иметь постепенно увеличивающиеся хэш-коды?Может быть, если есть сценарий, когда кто-то видел такое явление в прошлом, это может помочь мне пролить свет на двоичный файл, который я пытаюсь понять.

Короткий ответ:это интересно, но, конечно, не так.Рассматриваемый класс объекта генерирует hashCode() - это не имеет ничего общего с сериализацией, если по какой-то причине значение хэш-кода не было вычислено во время создания объекта, что будет намного более странным.

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

  • метод hashCode должен последовательно возвращать одно и то же целое число для одного и того же значения объекта, при условии, что информация, используемая в равныхизменение сравнения объекта
  • Если два объекта равны в соответствии с методом equals (Object), то вызов метода hashCode для каждого из двух объектов должен привести к одинаковому целочисленному результату
  • программист должен знать, что выдача различных целочисленных результатов для неравных объектов может улучшить производительность хеш-таблиц.

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

1 голос
/ 19 января 2012

Могут ли они быть последовательностью чисел?

Глядя на код для Integer и Long, их хеш-коды, по сути, состоят в том, что число и последовательные числа будут в значительной степени иметь последовательные хеш-коды.

Обратите внимание, что Long будет последовательным вплоть до Integer.MAX_VALUE, после этого он не будет таким последовательным, хотя все еще будет иметь хороший паттерн.

1 голос
/ 16 января 2012

Если вам нужно проверить наличие дубликатов, вы должны использовать метод equals вместо hashCode. Если вы читаете Javadoc для Object.hashCode, он говорит:

Не требуется, чтобы, если два объекта были неравны в соответствии с методом equals (java.lang.Object), то вызов метода hashCode для каждого из этих двух объектов должен давать разные целочисленные результаты.

Это означает, что вы можете иметь два объекта o1 и o2 с одинаковым значением hashCode, но где o1.equals(o2) = false. Вы будете обнаруживать ложный дубликат.

Чтобы проверить наличие дубликатов, вы можете использовать набор и проверять каждый добавленный объект, если Set.add(object) == true. Если он возвращает false, это означает, что он уже был в наборе.

Инкрементный хэш в вашем описании кажется мне очень плохой хэш-функцией, если только все объекты не принадлежат к одному классу и между ними также есть инкрементная связь. Например, запустите этот код:

    List l1 = Arrays.asList(1,2,3,4,5,6,7,8,9);
    for (Object object : l1) {
        System.out.println("hashCode: " + object.hashCode());
    }

Вы не говорите, являются ли объекты вашими собственными определенными классами. Если они были вашими, всегда помните, что если вы переопределяете equals, вы всегда должны переопределять также hashCode. Если нет, то вы нарушаете контракт hashCode, и некоторые классы (например, хешированные коллекции) могут вести себя не так, как вы ожидаете.

...