我有一个非常简单的 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 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());
}
}
然后我有一个 Position 类定义如下:
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());
}
}
这一切都很好。但是,当我尝试对其进行测试时,会发生一些奇怪的事情。
public class PositionTests extends TestCase {
private Position posOne;
private Position posTwo;
private Position posThree;
public PositionTests() {
posOne = new Position(7, 6);
posTwo = new Position(12, 7);
posThree = new Position(7, 6);
}
public void testCreationX() {
assertEquals(posOne.getX(), (Integer) 7);
}
public void testCreationY() {
assertEquals(posOne.getY(), (Integer) 6);
}
public void testEquality() {
// System.out.println("p1.e(p3): " + posOne.equals(posThree));
// System.out.println("p3.e(p1): " + posThree.equals(posOne));
//assertEquals(posOne, posThree);
assertEquals(posThree, posOne);
}
public void testInequality() {
assertFalse(posOne.equals(posTwo));
}
public void testXEquality() {
assertEquals(posOne.getX(), posThree.getX());
}
public void testYEquality() {
assertEquals(posOne.getY(), posThree.getY());
}
public void testSymmTrue() {
assertTrue(posOne.equals(posThree) == posThree.equals(posOne));
}
public void testSymmFalse() {
assertTrue(posOne.equals(posTwo) == posThree.equals(posTwo));
}
public void testHashSetSame() {
Set<Position> hSet = new HashSet<Position>();
hSet.add(posOne);
hSet.add(posThree);
hSet.add(posTwo);
hSet.add(posOne);
hSet.add(posOne);
hSet.add(posOne);
assertTrue(hSet.size() == 3);
}
public void testListContainsSuccess() {
List<Position> pList = new ArrayList<Position>();
pList.add(posOne);
pList.add(posTwo);
assertTrue(pList.contains(posOne));
}
public void testListContainsSuccessDiff() {
List<Position> pList = new ArrayList<Position>();
pList.add(posOne);
pList.add(posTwo);
// System.out.println(pList);
// System.out.println(posThree);
Boolean b = pList.contains(posThree);
System.out.println("contains: " + b);
assertTrue(pList.contains(posThree));
}
public void testListContainsFail() {
List<Position> pList = new ArrayList<Position>();
pList.add(posOne);
pList.add(posThree);
assertFalse(pList.contains(posTwo));
}
}
测试的相关输出如下:
[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
现在发布了我所有的相关代码和测试结果,我的问题是为什么 assertEquals(posOne, posThree) 以及对 contains() 的调用会失败?正如您在测试输出顶部看到的那样,.equals() 返回 true。我很困惑为什么这些失败。在我的整个程序中,我不得不使用手动列表遍历和手动调用 equals() 来检查列表成员,但为什么?List 的文档说
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)).
然而,.contains()
失败了。什么……?