Как Вы реализуете GetHashCode для структуры с два, представляют в виде строки, когда обе строки являются взаимозаменяемыми

Другое событие NullPointerException возникает, когда объявляется массив объектов, а затем сразу же пытается разыменовать его внутри.

String[] phrases = new String[10];
String keyPhrase = "Bird";
for(String phrase : phrases) {
    System.out.println(phrase.equals(keyPhrase));
}

Этот конкретный NPE можно избежать, если порядок сравнения отменяется ; а именно, использовать .equals для гарантированного непустого объекта.

Все элементы внутри массива инициализируются их общим начальным значением ; для любого типа массива объектов, это означает, что все элементы null.

Вы должны инициализировать элементы в массиве перед доступом или разыменованием их.

String[] phrases = new String[] {"The bird", "A bird", "My bird", "Bird"};
String keyPhrase = "Bird";
for(String phrase : phrases) {
    System.out.println(phrase.equals(keyPhrase));
}

67
задан Graviton 24 September 2014 в 11:28
поделиться

12 ответов

MSDN:

хеш-функция А должна иметь следующие свойства:

  • , Если два объекта выдерживают сравнение как равные, GetHashCode, метод для каждого объекта должен возвратить то же значение. Однако, если два объекта не выдерживают сравнение как равные, эти GetHashCode, методы для этих двух объектов не должны возвращать различные значения.
  • GetHashCode метод для объекта должен последовательно возвращать тот же хэш-код, пока нет никакой модификации к объектному состоянию, которое определяет возвращаемое значение объекта Equals метод. Обратите внимание, что это верно только для текущего выполнения приложения, и что различный хэш-код может быть возвращен, если приложение запущено снова.
  • Для лучшей производительности, хеш-функция должна генерировать случайное распределение для всего входа.

Взятие это во внимание исправляет путь:

return str1.GetHashCode() ^ str2.GetHashCode() 

^ может быть заменен с другой коммутативной операцией

66
ответ дан Motti 24 November 2019 в 14:37
поделиться
public override int GetHashCode()
{
    unchecked
    {
        return (str1 ?? String.Empty).GetHashCode() +
            (str2 ?? String.Empty).GetHashCode();
    }
}

Используя '+' оператор мог бы быть лучше, чем использование '^ ', потому что, хотя Вы явно хотите ('AA', 'BB') и ('BB', 'AA') явно быть тем же, Вы не можете хотеть ('AA', 'AA') и ('BB', 'BB') быть тем же (или все равные пары в этом отношении).

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

15
ответ дан 24 November 2019 в 14:37
поделиться
  1. Как правило, простым способом генерировать хэш-код для класса являются к XOR все поля данных, которые могут участвовать в генерации хэш-кода (старающийся для проверки на пустой указатель, как указано другими). Это также встречается (искусственный?) требование, чтобы хэш-коды для UserInfo ("AA", "BB") и UserInfo ("BB", "AA") были тем же.

  2. , Если можно сделать предположения об использовании класса, можно, возможно, улучшить хеш-функцию. Например, если str1 и str2 свойственно быть тем же, XOR не может быть хорошим выбором. Но если str1 и str2 представляют, скажем, имя и фамилию, XOR является, вероятно, хорошим выбором.

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

5
ответ дан Joe 24 November 2019 в 14:37
поделиться
public override int GetHashCode()   
{       
    unchecked      
    {           
        return(str1 != null ? str1.GetHashCode() : 0) ^ (str2 != null ? str2.GetHashCode() : 0);       
    }   
}
3
ответ дан user11556 24 November 2019 в 14:37
поделиться

А-ч да, как Gary Shutler указал:

return str1.GetHashCode() + str2.GetHashCode();

Может переполниться. Вы могли попытаться снять к долго в качестве Артема, предложенного, или Вы могли окружить оператор в ключевом слове непроверенном:

return unchecked(str1.GetHashCode() + str2.GetHashCode());
2
ответ дан Grokys 24 November 2019 в 14:37
поделиться

Испытайте этого:

(((long)str1.GetHashCode()) + ((long)str2.GetHashCode())).GetHashCode()
1
ответ дан Artem Tikhomirov 24 November 2019 в 14:37
поделиться

Много возможностей. Например,

return str1.GetHashCode() ^ str1.GetHashCode()

0
ответ дан VolkerK 24 November 2019 в 14:37
поделиться

Возможно, что-то как str1. GetHashCode () + str2. GetHashCode ()? или (str1. GetHashCode () + str2. GetHashCode ()) / 2? Таким образом, это было бы то же независимо от того, подкачиваются ли str1 и str2....

0
ответ дан Mike Stone 24 November 2019 в 14:37
поделиться

Отсортируйте их, затем свяжите их:

return ((str1.CompareTo(str2) < 1) ? str1 + str2 : str2 + str1)
    .GetHashCode();
0
ответ дан Steve Morgan 24 November 2019 в 14:37
поделиться

Результат GetHashCode, как предполагается:

  1. Максимально быстро.
  2. Максимально уникальный.

Мысль о тех, я пошел бы с чем-то вроде этого:

if (str1 == null)
    if (str2 == null)
        return 0;
    else
       return str2.GetHashCode();
else
    if (str2 == null)
        return str1.GetHashCode();
    else
       return ((ulong)str1.GetHashCode() | ((ulong)str2.GetHashCode() << 32)).GetHashCode();

Редактирование: Забыл пустые указатели. Код зафиксирован.

0
ответ дан Omer van Kloeten 24 November 2019 в 14:37
поделиться

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

if (null != str1) {
    return str1.GetHashCode();
}
if (null != str2) {
    return str2.GetHashCode();
}
//Not sure what you would put here, some constant value will do
return 0;

, Это смещается путем предположения, что str1 вряд ли будет распространен в необычно значительной доле экземпляров.

-1
ответ дан LPL 24 November 2019 в 14:37
поделиться

См. Ответ Джона Скита - бинарные операции вроде ^ не подходят, они часто генерируют конфликтующий хеш!

26
ответ дан 24 November 2019 в 14:37
поделиться
Другие вопросы по тегам:

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