HashSet似乎没有意识到两个对象是相同的。
我正在尝试使用HashSet来存储我创建的类的对象,但显然相同的对象似乎有两个不同的哈希值,这就是为什么contains方法没有意识到该对象已经在HashSet中。 这导致我的程序耗尽堆内存。
我不认为我做错了什么,但无论如何我想要第二意见。 我做过类似的操作,之前一切正常,这使得这特别烦人。 我很感激任何帮助。
这是我的代码
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");
这是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); } }
这是我得到的输出
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.(makeMove.java:33)
您需要覆盖Move
类中的Object#hashCode()
方法,以使其返回Move
实例状态的相同hashCode()
值。 不要忘记重写Object#equals()
。
也可以看看:
- 在Java中覆盖equals和hashCode
提示 :如果你使用像Eclipse这样的IDE,你也可以自动生成它们。 右键单击Move
类,选择Source> Generate hashCode()和equals() 。 这是它的样子:
@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; }
HashSet将基于调用hashCode()和equals()来确定相等性。 您尚未实现这些,因此您将从Objectinheritance它们。 Object的hashCode和equals方法仅基于引用是否相等。
这就是为什么if(move1.hashCode()==new Move(t,s).hashCode())
为false。 move1是一个不同于通过调用new Move(t,s).hashCode()创建的实例的实例。
您需要在Move类中实现hashCode和equals。
例如(虽然可能是非最优的,你可能想要一个null安全等于 – 如果可以,你的IDE会生成它们)
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; }
你必须覆盖equals()和hasCode()
这可能是一种选择。
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() ); } }
您必须定义移动的顺序是否相关(1,2等于2,1或不是)
了解更多信息:
在Java中覆盖equals和hashCode时应该考虑哪些问题?
第8项:当你覆盖equals from:“Effective Java” http://bit.ly/cd7uUl时,总是覆盖hashCode