Agregar matrices con los mismos valores a los resultados de HashSet en elementos duplicados

Estoy tratando de crear un conjunto de matrices de entradas, lo que ocurre es que si trato de hacer:

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());

Entonces s tiene dos objetos, pero solo debe haber uno. Nota: no importa si es HashSet <Integer []>. Simplemente no funciona.

Ahora, si trato de hacer esto con un ArrayList <Integer>, algo como:

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());

Entonces s tiene un objeto.

Pensé en una forma de evitar el error en el primer código y estaba almacenando los hashcodes de cada matriz en un hashset de la siguiente manera:

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());

Funciona para el primer caso (1,2,3), pero en los casos en que hay colisiones, no funciona, por lo que tendría que gestionar las colisiones. Entonces, creo que lo que estoy haciendo es implementar un HashSet por mí mismo.

Con HashSet <ArrayList <Integer >> funciona perfectamente. Supongo que Java manejará las colisiones en ese caso.

Mi pregunta es por qué Java no permite administrar un HashSet <int []> o HashSet <Integer []> si los hashcodes generados son los mismos que en ArrayList <Integer> y los hashcodes de las matrices se pueden calcular simplemente llamando Arrays.hashCode ( ...).

Y finalmente, si quiero hacer un HashSet <int []> (o HashSet <Integer []>), ¿tendría que implementarlo por mí mismo? ¿O hay una mejor manera de hacerlo?

Gracias.

ACTUALIZAR: Ok, finalmente creo que he llegado a una respuesta completa. Como @ZiyaoWei y @ user1676075 comentaron, no funciona porque igual devuelve falso y los hashcodes son diferentes. Pero, ¿por qué java no anula estos métodos (con Arrays.equals (), Arrays.hashCode ()) para que uno pueda hacer algo como HashSet <int []>? La respuesta es porque una matriz es un objeto mutable, y el código hash no puede depender de valores mutables (cada elemento de la matriz es un valor mutable) de acuerdo con el contrato general de código hash.Objetos mutables y hashCode

Aquí explicaciones agradables de usar campos mutables en hashCodehttp://blog.mgm-tp.com/2012/03/hashset-java-puzzler/ y claves mutables en los hashmaps¿Son las claves mutables de hashmap una práctica peligrosa?

Mi respuesta es: si desea usar un HashSet <int []>, debe crear una clase que tenga una matriz y si desea que el código hash y el igual dependan de los valores, los métodos de reemplazo son iguales () y hashCode () con Arrays .equals () y Arrays.hashCode (). Si no quieres violar el contrato, haz que la matriz sea definitiva.

¡Gracias a todos!

Respuestas a la pregunta(2)

Su respuesta a la pregunta