Pull to refresh

Comments 43

UFO just landed and posted this here
UFO just landed and posted this here
я смотрю, там понеслось :)

На самом деле, сейчас самое время менять дефолтное поведение: в восьмёрке JCK, скорее всего, пропустит это изменение, а в 7uXX или 8uXX может быть чревато по причинам, описанным Дэвидом:
This kind of switch can not be made lightly. It is not just a matter of raw performance, we have to understand how the change might affect existing applications. The default affects thousands of programs.


Так что, имхо, сейчас самое время.
UFO just landed and posted this here
Дико извиняюсь, возможно неправильно понял но разве не должны два отдельных объекта которые equals возвращать одинаковый хашкод? Иначе как в хаштабах искать?
UFO just landed and posted this here
Но есть ньюанс:

If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.

It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hashtables.


docs.oracle.com/javase/1.4.2/docs/api/java/lang/Object.html#hashCode()
UFO just landed and posted this here
Я специально процитировал, т.к. в изначальном вопросе не было уточнено, переопределены ли equals(). Ну и последнее предложение второй цитаты тоже достаточно интересно.
UFO just landed and posted this here
Так в том и фишка что " Два разных объекта (т.е. созданные разными new) будут всегда не равны по Object.equals". Соответственно раз они не равны то и хаши никому ничего не обязаны.
> However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hashtables.
Т.е. вы предполагаете что созданный объекты через «new» 2жды будет уметь разные хеши и equals на них вернет false?
Для примера: Object o1 = new Object(«test») и Object o2 = new Object(«test»); из ваших слов будут иметь разные хеши.
Так ли я вас понял?
> Для примера: Object o1 = new Object(«test») и Object o2 = new Object(«test»); из ваших слов будут иметь разные хеши.

Зависит от Object. Если это нечто вроде Integer или String — то хэши будут одни, и equals() вернет true.
А если нечто вроде org.eclipse.jetty.server.Server.Server(8080), то очевидно хэши будут разные.
А вообще, если, как мне сказали выше, речь идет о «В топике обсуждается Object.hashCode(), т.е. поведение базового хешкода, пришедшего из суперкласса Object.», то Object не принимает в конструктор аргументов.
Все правильно только здесь речь идет о стандартной имплементации для класса Object. Как часто ты использовал его в качестве ключа и какие объекты считать равными. Поэтому все довольно логично
Если хешкод генерится случайно во время первого вызова, то получается, что у двух разных объектов могут совпасть хешкоды (хоть и с малой вероятностью)?
UFO just landed and posted this here
Конечно. Хотя бы потому, что они ограничены объёмом int -1, раз 0 не годится за правильный хэшкод.
в оригинальном посте даже указан ключ когда все они будут константой :D насколько понимаю тут баланс между затратами на генерацию и затратами на дальнейший поиск по такому хэшу — если у многих объектов он совпадает то поиск будет дольше.
Если размер множества допустимых значений объектов класса больше 2 ** 32, то в любом случае будут совпадения хешей у разных объектов.
Они могут совпасть и из-за race condition, когда для двух объектов впервые вызывается hashCode из разных тредов почти одновременно:
533 // This form uses an unguarded global Park-Miller RNG,
534 // so it's possible for two threads to race and generate the same RNG.
Сначала попался на глаза крайне несправедливо заминусованный комментарий. Именно SSSurkv совершенно верно предположил, что для вычисления Object.hashCode используется генератор случайных чисел.

Вообще в топике, к которому был тот комментарий, речь шла про Android, где, как вы сами же и написали, всё-таки используется адрес.

И, кстати, всё-таки непонятно, чем плох вариант с адресом:
1) То, что значения последовательные, не должно особо на что-то влиять, так как все реализации Map, которые я видел, не используют хэш напрямую, а вычисляют на его основе ещё один хэш — как раз, чтобы добиться равномерного распределения по бакетам.
2) Какая разница, что адрес меняется, если, аналогично рандому, его можно считать только один раз?
Единственное, что приходит в голову, это то, что если использовать адреса, то, видимо, множество возможных хэшей становится сильно ограниченным.

И ещё мне интересно, а как реализуется, что хэш вычисляется только при первом обращении? Там, получается, блокировка должна быть?
И ещё мне интересно, а как реализуется, что хэш вычисляется только при первом обращении? Там, получается, блокировка должна быть?
На сколько я понимаю из вышеприведённых исходников, там используются bias-locking (очень легковесный лок) и атомарная операция для присвоения нового хэша, если его нет. Если атомарная операция фейлится, используется более тяжелый лок.

Спасибо автору поста, первый раз смотрю в сорцы JDK, интересно.
Блин, точно — не сообразил посмотреть, где используется get_next_hash.
Спасибо :)
UFO just landed and posted this here
Поправьте меня, если я не права: рандом используется в jdk7, а в jdk6 это был всё же адрес, который сохранялся в заголовке так же как сохраняется рандом в jdk7?
UFO just landed and posted this here
Удивительно, но официальный javadoc намекает, что это таки адрес в памяти, а так же многие гайды это говорят. Это, конечно, не существенно, но как-то обидно, когда javadoc врет, хоть и намеками, о поведении JDK от Oracle/SUN…
UFO just landed and posted this here
Может это конечно и не верно с моей стороны, но я общаюсь только с Oracle JVM, и если у них в javadoc указано, что ТИПИЧНОЕ поведение вот такое, то я закономерно ожидаю его от Oracle JVM, потому что это как бы ТИПИЧНАЯ JVM.
UFO just landed and posted this here
На самом деле, мне без разницы как считается hash code у Object, комментарий был не об этом, а о том, что некоторые вещи в яве не очевидны…
UFO just landed and posted this here
забавный факт: хотспотовский hashCode никогда не вернет 0

А как же null?
Для null, очевидно, хеш-код не генерируется. Но System.identityHashCode(null) возвращает 0 — все верно.
Так, всего лишь добавив ключ JVM -XX:hashCode=5, я магическим образом ускорил свой алгоритм на 30%!


Интересно, а какой use-case, что потребовался system hash code, а не штатный, скорее всего переопределённый?
Сериализация графа объектов.
спрошу здесь в надежде, что увидят и ответят: почему hashCode возврщает именно int, а не long? это так исторически так сложилось или есть какая-то объективная причина?
Так исторически сложилось + объективная причина, что на 32-разрядных архитектурах работа с long быстрее и экономнее. Во времена JDK 1.x 64-разрядных систем ещё не было.

См. http://stackoverflow.com/questions/4166195/why-objecthashcode-returns-int-instead-of-long
Sign up to leave a comment.

Articles