Java 奇怪的断言包含了行为
我有一个非常简单的Pair类,定义如下:Java 奇怪的断言包含了行为,java,list,junit,Java,List,Junit,我有一个非常简单的Pair类,定义如下: public class Pair<L, R> { private L left; private R right; public Pair(L left, R right) { this.left = left; this.right = right; } public L getLeft() { return this.left; }
public class Pair<L, R> {
private L left;
private R right;
public Pair(L left, R right) {
this.left = left;
this.right = right;
}
public L getLeft() {
return this.left;
}
public R getRight() {
return this.right;
}
public String toString() {
return String.format("(%s, %s)", left, right);
}
public int hashCode() {
int hashFirst = left != null ? left.hashCode() : 0;
int hashSecond = left != null ? right.hashCode() : 0;
return (hashFirst + hashSecond) * hashSecond + hashFirst;
}
public Boolean equals(Pair other) {
if (other == null) {
return false;
}
return left.equals(other.getLeft()) && right.equals(other.getRight());
}
}
public class Position {
private Pair<Integer, Integer> pair;
public Position(Integer x, Integer y) {
this.pair = new Pair<Integer, Integer>(x, y);
}
public Integer getX() {
return this.pair.getLeft();
}
public Integer getY() {
return this.pair.getRight();
}
public boolean equals(Position other) {
if (other == null) {
return false;
}
boolean b = getX() == other.getX() && getY() == other.getY();
System.out.println(String.format("%s.equals(%s): %s", this, other, b));
return b;
}
public int hashCode() {
return pair.hashCode();
}
public String toString() {
return String.format("(%d, %d)", this.pair.getLeft(),
this.pair.getRight());
}
}
[junit] ------------- Standard Output ---------------
[junit] JUnit version is: 3.8.2
[junit] contains: false
[junit] (7, 6).equals((7, 6)): true
[junit] (7, 6).equals((7, 6)): true
[junit] (7, 6).equals((12, 7)): false
[junit] (7, 6).equals((12, 7)): false
[junit] (7, 6).equals((12, 7)): false
[junit] (7, 3).equals((7, 4)): false
[junit] ------------- ---------------- ---------------
[junit]
[junit] Testcase: testListContainsSuccessDiff took 0.005 sec
[junit] FAILED
[junit] null
[junit] junit.framework.AssertionFailedError
[junit] at com.group7.dragonwars.tests.PositionTests.testListContainsSuccessDiff(PositionTests.java:92)
[junit]
[junit] Testcase: testListContainsFail took 0 sec
[junit] Testcase: testYEquality took 0 sec
[junit] Testcase: testSymmTrue took 0.014 sec
[junit] Testcase: testSymmFalse took 0.001 sec
[junit] Testcase: testHashSetSame took 0 sec
[junit] Testcase: testListContainsSuccess took 0 sec
[junit] Testcase: testCreationY took 0 sec
[junit] Testcase: testEquality took 0.001 sec
[junit] FAILED
[junit] expected:<(7, 6)> but was:<(7, 6)>
[junit] junit.framework.AssertionFailedError: expected:<(7, 6)> but was:<(7, 6)>
[junit] at com.group7.dragonwars.tests.PositionTests.testEquality(PositionTests.java:43)
[junit]
[junit] Testcase: testInequality took 0.001 sec
[junit] Testcase: testXEquality took 0 sec
[junit] Testcase: testCreationX took 0 sec
[junit] Test com.group7.dragonwars.tests.AllTests FAILED
然而,
.contains()
失败了。什么是…?如果在equals()方法中添加@Override
注释,您将看到问题。参数类型必须是对象
,而不是位置
@Override
public boolean equals(Object other) {
另外,Pair.hashCode()
中有一个输入错误
您希望位置和对上的相等值接受一个对象——您只是用接受对的声明重载它 另外,您在Pair上的hashCode实现也很奇怪:)可能使用Apache EqualBuilder和HashBuilder类
相关javadoc:哦,哇,我这辈子都在做错事。非常感谢你。是的,哈希代码中的诚实错误!非常感谢。
Returns true if this list contains the specified element. More formally, returns true if and only if this list contains at least one element e such that (o==null ? e==null : o.equals(e)).
@Override
public boolean equals(Object other) {
int hashFirst = left != null ? left.hashCode() : 0;
int hashSecond = left != null ? right.hashCode() : 0;
^^^^^