При каких обстоятельствах при правильной реализации hashCode и equals() может ли следующий код вернуть false?java hashtable содержит странность
myLinkedHashMap.containsKey(myLinkedHashMap.keySet().iterator().next())
При каких обстоятельствах при правильной реализации hashCode и equals() может ли следующий код вернуть false?java hashtable содержит странность
myLinkedHashMap.containsKey(myLinkedHashMap.keySet().iterator().next())
Скорее всего, сценарий, о котором я могу думать, будет, хотя hashCode
является «детерминированным», он может быть основан на изменяемых полях. Если вы измените поля, используемые для вычисления hashCode
после того, как он будет помещен в Map
, вы не сможете его найти.
Редактировать: следует уточнить, что вы «обычно» больше не сможете его найти. Иногда он все равно будет работать, поскольку два номера могут снова перефразировать в одно и то же ведро. Это, конечно, только добавляет к путанице, когда это происходит!
yep, мутация. Благодарю. –
Это не ясно, что вы имеете в виду под «детерминированный», но любой хэш-изменение мутации к ключу после того как она вставлена в хэш-карта может легко иметь такой эффект.
import java.util.*;
public class Test {
public static void main(String[] args) {
List<String> strings = new ArrayList<String>();
Map<List<String>, String> map = new LinkedHashMap<List<String>, String>();
map.put(strings, "");
System.out.println(map.containsKey(map.keySet().iterator().next())); // true
strings.add("Foo");
System.out.println(map.containsKey(map.keySet().iterator().next())); // false
}
}
Хэш код ArrayList<T>
является детерминированным, но это не означает, что она не изменится, если содержимое изменений списка.
Если ваши hashCode
и equals
не согласны друг с другом, это может вернуть значение false. Например, если метод equals
всегда возвращает false
, это вернет false
, так как нет объектов, которые бы никогда не сравнивались с ключами на карте.
Надеюсь, это поможет!
Если hashCode()
основан на атрибутах экземпляра, которые изменяемых и те атрибуты, которые изменяются после вставки, то hashCode()
вызова во время итерации будет возвращать что-то другое. И equals()
должен основываться на этих же атрибутах, и ожидается, что он также потерпит неудачу.
Когда другой поток удалены все следующие элементы из Map
в середине итерации, не будет больше next()
.
Я бы не использовать hashCode()
значения как ключи, я бы вы сами объекты.
нет нитей .. –
не имеет значения, не влияет ли ваш конкретный экземпляр, который вы думаете, не один, а ваш вопрос **, когда это может случиться, это один случай, который может произойти. –
Возможно, вы сначала захотите проверить hasNext().
нет, это есть. Определенно есть элементы. –
Каждый алгоритм хэша, который я видел, является «детерминированным», в том, что для заданного набора входных значений вы получаете одинаковое значение хэш-функции.
Если хэш-код вычисляется на основе изменяемых свойств объекта, хеш-код будет изменен после того, как он будет отображен в хэш-карте, если будет изменено какое-либо из этих изменяемых свойств.
Вы можете удалить первый ключ в другой поток между получением первых ключей и вызовом containsKey.
Под «детерминированным» подразумевается «правильный»? –
В этом случае это не имеет значения, потому что это тот же объект, не так ли? Таким образом, пока 2 вызова на одном и том же объекте производят один и тот же хэш-код, это должно возвращать true. Но да, это тоже правильно. –
Но «детерминированный» не означает «2 вызова на одном и том же объекте производят один и тот же хэш-код». Нет ничего * недетерминированного * о 'ArrayList .hashCode', но см. Мой ответ ... –