Добавление массивов с одинаковыми значениями в HashSet приводит к дублированию элементов

Я пытаюсь создать набор массивов целых, дело в том, что если я попытаюсь сделать:

HashSet<int[]> s = new HashSet<int[]>();
int a1[] = {1,2,3};
int a2[] = {1,2,3};
s.add(a1);
s.add(a2)
System.out.println(s.size());

Тогда s имеет два объекта, но должен быть только один. Примечание: не имеет значения, если это HashSet <Integer []>. Это просто не работает.

Теперь, если я попытаюсь сделать это с ArrayList <Integer>, что-то вроде:

HashSet<ArrayList<Integer>> s = new HashSet<ArrayList<Integer>>();
ArrayList<Integer> a1 = new ArrayList<Integer>();
ArrayList<Integer> a2 = new ArrayList<Integer>();
a1.add(1);
a1.add(2);
a1.add(3);

a2.add(1);
a2.add(2);
a2.add(3);

s.add(a1);
s.add(a2)
System.out.println(s.size());

Тогда у s есть один объект.

Я нашел способ избежать ошибки в первом коде и хранить хэш-коды каждого массива в хэш-наборе следующим образом:

int a1[] = {0,10083,10084,1,0,1,10083,0,0,0,0};
int a2[] = {1 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,1 ,0,2112};
HashSet<Integer> s= new HashSet<Integer>();//hashcodes of each array
s.add(Arrays.hashCode(a1));
s.add(Arrays.hashCode(a2));
System.out.println(Arrays.hashCode(a1));
System.out.println(Arrays.hashCode(a2));
System.out.println(s.size());

Это работает для первого случая (1,2,3), но в случаях, когда есть столкновения, это не работает, поэтому мне придется управлять столкновениями. Итак, я думаю, что я занимаюсь реализацией HashSet самостоятельно.

С HashSet <ArrayList <Integer >> это работает отлично. Я полагаю, что Java управляет коллизиями в этом случае.

Мой вопрос заключается в том, почему java не позволяет управлять HashSet <int []> или HashSet <Integer []>, если сгенерированные хэш-коды такие же, как в ArrayList <Integer> и хеш-коды массивов можно вычислить, просто вызвав Arrays.hashCode ( ...).

И, наконец, если я хочу сделать HashSet <int []> (или HashSet <Integer []>), мне придется реализовать его самостоятельно? Или есть лучший способ сделать это?

Благодарю.

ОБНОВИТЬ: Хорошо, наконец, я думаю, что пришел к полному ответу. Как прокомментировали @ZiyaoWei и @ user1676075, он не работает, потому что equals возвращает false, а хеш-коды являются разными. Но почему java не переопределяет эти методы (с Arrays.equals (), Arrays.hashCode ()), чтобы можно было сделать что-то вроде HashSet <int []>? Ответ заключается в том, что массив является изменяемым объектом, и хеш-код не может зависеть от изменяемых значений (каждый элемент массива является изменяемым значением) в соответствии с общим контрактом хеш-кода.Изменяемые объекты и hashCode

Здесь хорошие объяснения использования изменяемых полей в hashCodehttp://blog.mgm-tp.com/2012/03/hashset-java-puzzler/ и изменяемые ключи в hashmapsЯвляются ли изменяемые ключи hashmap опасной практикой?

Мой ответ таков: если вы хотите использовать HashSet <int []>, вам нужно создать класс с массивом, и если вы хотите, чтобы этот хэш-код и equals зависели от значений, переопределите методы equals () и hashCode () с Arrays. .equals () и Arrays.hashCode (). Если вы не хотите нарушать договор, просто сделайте массив окончательным.

Всем спасибо!

Ответы на вопрос(2)

Ваш ответ на вопрос