example java hashset

hashset java example



HashSet no parece darse cuenta de que dos objetos son iguales. (3)

Estoy tratando de usar HashSet para almacenar objetos de una clase que creé, pero aparentemente los mismos objetos parecen tener dos hashes diferentes, por lo que el método contiene no se da cuenta de que el objeto ya está en el HashSet. Esto hace que mi programa se quede sin memoria de almacenamiento dinámico.

No creo que esté haciendo nada malo, pero quería una segunda opinión de todos modos. He hecho operaciones similares antes de que todo funcionara bien, lo que hace que esto sea particularmente molesto. Apreciaría cualquier ayuda.

Aquí está mi código

move1 = new Move(t,s); if(move1.hashCode()==new Move(t,s).hashCode()) System.out.println("match"); move2 = new Move(s,t); moves.add(move1); moves.add(move2); if(moves.contains(new Move(t,s))) System.out.println("match found");

Aquí está la clase Move:

public class Move { private int move1; private int move2; Move(int m1, int m2) { move1 = m1; move2 = m2; } public String toString() { return String.valueOf(move1)+" "+String.valueOf(move2); } }

Aquí está la salida que recibo

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at java.util.HashMap.addEntry(HashMap.java:797) at java.util.HashMap.put(HashMap.java:431) at java.util.HashSet.add(HashSet.java:194) at makeMove.<init>(makeMove.java:33)


HashSet determinará la igualdad en función de las llamadas a hashCode () y equals (). No los has implementado, así que los heredarás de Object. Los métodos hashCode y equals de Object solo se basan en si las referencias son iguales.

Es por eso que if(move1.hashCode()==new Move(t,s).hashCode()) es falso. move1 es una instancia diferente a la instancia creada al llamar nuevo Move (t, s) .hashCode ()

Tendrá que implementar hashCode y es igual en su clase Move.

por ejemplo (aunque quizás no sea óptimo, y es posible que desee un nulo seguro igual a igual, haga que su IDE los genere si es posible)

public int hashCode() { return move1 ^ move2 +; } public boolean equals(Object o) { if(!other instanceof Move) return false; Move other = (Move)o; return other.move1 == move1 && other.move2 == move2; }


Tienes que anular equals() y hasCode()

Esta puede ser una opción.

import static java.lang.System.out; public class Move { private int move1; private int move2; Move(int m1, int m2) { move1 = m1; move2 = m2; } public String toString() { return String.valueOf(move1)+" "+String.valueOf(move2); } public int hashCode() { return move1 * 31 + move2 * 31; } public boolean equals( Object other ) { if( this == other ) { return true; } if( other instanceof Move ) { Move m2 = ( Move ) other; return this.move1 == m2.move1 && this.move2 == m2.move2; } return false; } public static void main( String [] args ) { out.println( new Move(2,3).equals( new Move(2,3))); out.println( new Move(1,1).hashCode() == new Move(1,1).hashCode() ); } }

Debe definir si el orden del movimiento es relevante (1,2 es igual a 2,1 o no)

Para más información:

¿Qué problemas se deben considerar cuando se reemplaza equals y hashCode en Java?

Elemento 8: siempre anula el código de hash cuando anulas iguales de: "Java efectiva" http://bit.ly/cd7uUl


Object#hashCode() anular el método Object#hashCode() en la clase Move para permitirle devolver el mismo valor hashCode() para el estado de la instancia de Move . No te olvides de anular también Object#equals() .

Ver también:

Consejo : si está utilizando un IDE como Eclipse , también puede autogenerarlos. Haga clic con el botón derecho en alguna parte de la clase Move , elija Fuente> Generar código hash () y es igual a () . Así es como se ve entonces:

@Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + move1; result = prime * result + move2; return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Move other = (Move) obj; if (move1 != other.move1) return false; if (move2 != other.move2) return false; return true; }