java - Weird assertEquals and contains behaviour -
i have simple pair class defined follows:
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()); } }
i have position class defined follows:
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()); } }
that's nice. peculiar happens when try test it.
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)); } }
the relevant output test follows:
[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] @ 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)> was:<(7, 6)> [junit] junit.framework.assertionfailederror: expected:<(7, 6)> was:<(7, 6)> [junit] @ 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
having posted relevant code , test results, question why assertequals(posone, posthree) calls contains() fail? can see @ top of tests output, .equals() returns true. i'm confused why these fail. throughout program i've had use manual list traversal , manually calling equals() check list membership, why? documentation list says
returns true if list contains specified element. more formally, returns true if , if list contains @ least 1 element e such (o==null ? e==null : o.equals(e)).
and yet, .contains()
fails. the…?
if add @override
annotation equals() method you'll see problem. parameter type must object
, not position
.
@override public boolean equals(object other) {
also, there's typo in pair.hashcode()
.
int hashfirst = left != null ? left.hashcode() : 0; int hashsecond = left != null ? right.hashcode() : 0; ^^^^^
Comments
Post a Comment