#java #hashcode
#java #хэш-код
Вопрос:
Class A {
private String test1;
private String test2;
}
Class Feature {
private List<A> obj;
/*
HashCode which should return same value even though i change ordering of objects in List
*/
}
Текущее поведение:
> List<A> contains [obj1, obj2, obj3] -> Some hashCode (Ex: 9058203945)
> List<A> contains [obj2, obj1, obj3] -> Some other hashCode (Ex:-23423423)
Я хочу, чтобы мой хэш-код списка был таким же, если я изменю порядок элементов в списке.
Любая помощь?
Заранее спасибо
Комментарии:
1. Ваш вопрос неясен. Вы говорите о результате
hashCode
метода onList
?2. Напишите свой метод хэш-кода таким образом, чтобы порядок элементов не имел значения. Например, возьмите XOR хэш-кодов элементов. Другим способом было бы использовать a
Set
вместо aList
.3. Хэш-код класса объектов зависит от
List<A>
хэш-кода, что в основном означает, что вы хотели бы изменить поведение (например) Функция хэш-кода ArrayList, которая невозможна. Вам придется переопределить функцию hashCode вашего класса. Кроме того, заказы обычно имеют значение в хэше. Это действительно плохая практика — не заботиться о заказах в хеш-функции.
Ответ №1:
Не уверен, но я предполагаю, что вы имеете в виду List#hashCode
метод.
Упорядочение элементов — это само определение List
Порядок элементов, содержащихся в a List
, является основной концепцией списка. Таким образом, изменение порядка приводит к появлению совсем другого списка. Эти два списка концептуально не равны, поэтому они не возвращают и не должны возвращать одно и то же значение хэша (за исключением случайного совпадения, что чрезвычайно редко при использовании приличной хэш-функции).
Технически вы можете создать подкласс List
класса и переопределить hashCode
метод. Вы можете делать все, что вам нравится, в своем собственном hashCode
методе. Но это было бы очень плохой идеей, поскольку это нарушает семантику a List
.
Set
Если вас не волнует порядок ваших элементов, вместо этого используйте другую коллекцию List
.
Set
вероятно, это то, что вам нужно. A Set
содержит кучу объектов, не обязательно в каком-либо определенном порядке. Некоторые реализации повторяются в определенном порядке, некоторые не обещают никакого порядка.
Set < DayOfWeek > setX = Set.of( DayOfWeek.TUESDAY , DayOfWeek.WEDNESDAY );
Set < DayOfWeek > setY = Set.of( DayOfWeek.WEDNESDAY , DayOfWeek.TUESDAY );
boolean sameHashCode = ( setX.hashCode() == setY.hashCode() );
System.out.println( "setX.hashCode() = " setX.hashCode() );
System.out.println( "setY.hashCode() = " setY.hashCode() );
System.out.println( "sameHashCode = " sameHashCode );
При запуске.
setX.hashCode() = -838114520
setY.hashCode() = -838114520
sameHashCode = true
Это работает в разных реализациях Set
.
Set < DayOfWeek > setX =new TreeSet<>() ;
setX.add( DayOfWeek.TUESDAY);
setX.add( DayOfWeek.WEDNESDAY);
Set < DayOfWeek > setY = new HashSet <>();
setY.add( DayOfWeek.WEDNESDAY );
setY.add( DayOfWeek.TUESDAY );
boolean sameHashCode = ( setX.hashCode() == setY.hashCode() );
sameHashCode = true
Это были объекты enum выше. Работает ли это с String
объектами? ДА.
Set < String > setX = new TreeSet <>();
setX.add( "Alice" );
setX.add( "Bob" );
setX.add( "Carol" );
Set < String > setY = new HashSet <>();
setY.add( "Bob" );
setY.add( "Alice" );
setY.add( "Carol" );
boolean sameHashCode = ( setX.hashCode() == setY.hashCode() );
sameHashCode = true
Set
отличается
Имейте в виду одно существенное различие между Set
и List
:
List
позволяет дублировать. Один объект может быть добавлен в список несколько раз и занимать несколько слотов в этом списке.Set
запрещает дублирование. ASet
отличается, содержит только одну ссылку на какой-либо конкретный объект. Добавление одного конкретного объекта несколько раз не имеет никакого эффекта после первого раза.
Чтобы процитировать Set
Javadoc:
Коллекция, которая не содержит повторяющихся элементов. Более формально, наборы не содержат пары элементов e1 и e2, таких, что e1.equals(e2), и не более одного нулевого элемента. Как следует из его названия, этот интерфейс моделирует абстракцию математического множества.
Set < String > setY = new TreeSet <>();
setY.add( "Jan" );
setY.add( "Marsha" );
setY.add( "Marsha" );
setY.add( "Marsha" );
setY.add( "Cindy" );
setY.toString(): [Синди, Ян, Марша]
Комментарии:
1. Хорошо объяснено! Для будущих посетителей эта ссылка может быть полезна для лучшего понимания
hashCode
иequals
методовList
.2. Все мои сомнения устранены, спасибо @Basil Bourque.