HashSet vs TreeSet contans()

HashSet vs TreeSet contans()
2017-07-09T20:48:48+02:00
2017-07-09T21:45:43+02:00
2022-10-15T22:25:25+02:00
KrixKrax
Adott egy Pair osztály, ami párokat tartalmaz:

static class Pair implements Comparable<Pair> { int i; int j; public Pair(int i, int j) { this.i = i; this.j = j; } @Override public int hashCode() { return Objects.hash(this.i, this.j); } @Override public int compareTo(Pair other) { int compare = Integer.compare(i, other.i); if (compare != 0) { return compare; } else { return Integer.compare(j, other.j); } } @Override public String toString(){ return "(" + i + "," + j + ";" + hashCode() + ")"; } }
Ezeket TreeSet-be illetve HashSet-be teszem bele, hogy meg tudjam állapítani, hogy találkoztam-e már a soron következővel. Meglepődtem, hogy a két implementációval különböző eredményt kaptam:

@Test public void test() { Pair p1 = new Pair(1, 2); Pair p2 = new Pair(1, 2); Pair p3 = new Pair(3, 3); Assert.assertNotEquals(p1.hashCode(), p3.hashCode()); Assert.assertEquals(p1.hashCode(), p2.hashCode()); } @Test public void testTreeSet() { Set<Pair> values = new TreeSet<>(); Pair p1 = new Pair(1, 2); Pair p2 = new Pair(1, 2); Pair[] pairs = new Pair[] { p1, p2 }; for (Pair p : pairs) { if (!values.contains(p)) { values.add(p); } } System.out.println(); Assert.assertEquals(1, values.size()); } @Test public void testHashSet() { Set<Pair> values = new HashSet<>(); Pair p1 = new Pair(1, 2); Pair p2 = new Pair(1, 2); Pair[] pairs = new Pair[] { p1, p2 }; for (Pair p : pairs) { if (!values.contains(p)) { values.add(p); } } }
Mi lehet ennek az oka? Előre is köszönöm.
Mutasd a teljes hozzászólást!
Nem implementáltad az equals() metódust, márpedig a HashSet tutira azt használja annak az eldöntésére, hogy az adott elem benne van-e már. A TreeSet valószínűleg a compareTo() metódust hívja ugyanennek az eldöntésére.

Úgy általában ökölszabályként elmondható, hogy vagy együtt kell implementálnod az equals() és a hashCode() metódusokat, vagy mindkettőt meg kell hagynod az Object osztály verziójának. A két metódus működése annyira összefügg, hogy csak az egyik működését módosítva tuti, hogy valahol gondot fog okozni.
Mutasd a teljes hozzászólást!

  • Ha szeretsz nyomozni, akkor kövesd végig, hogy mit használ a háttérben a két contains() metódus: TreeSet.contains() - HashSet.contains()

    Gondolatébresztőnek: biztos, hogy mindkettő a compareTo-val hasonlítja össze a két objektumot? 
    Mutasd a teljes hozzászólást!
  • Nem implementáltad az equals() metódust, márpedig a HashSet tutira azt használja annak az eldöntésére, hogy az adott elem benne van-e már. A TreeSet valószínűleg a compareTo() metódust hívja ugyanennek az eldöntésére.

    Úgy általában ökölszabályként elmondható, hogy vagy együtt kell implementálnod az equals() és a hashCode() metódusokat, vagy mindkettőt meg kell hagynod az Object osztály verziójának. A két metódus működése annyira összefügg, hogy csak az egyik működését módosítva tuti, hogy valahol gondot fog okozni.
    Mutasd a teljes hozzászólást!
Tetszett amit olvastál? Szeretnél a jövőben is értesülni a hasonló érdekességekről?
abcd