chciałem sobie posortować liście na podstawie ich koloru, użyłem TreeSet'a, jaki będzie wynik funkcji shouldTestTreeSet(), jaka będzie kolejność liści?
class Leaf{ int color; int size; public Leaf(int color, int size) { this.color = color; this.size = size; } @Override public boolean equals(Object obj) { if (obj == this) return true; if (!(obj instanceof Leaf)) return false; Leaf leaf = (Leaf) obj; return new EqualsBuilder().append(this.color, leaf.color) .append(this.size, leaf.size).isEquals(); } @Override public int hashCode() { return new HashCodeBuilder().append(color).append(size).toHashCode(); } @Override public String toString() { return String.valueOf(color + " " +size); } } class LeafComparator implements Comparator<Leaf>{ @Override public int compare(Leaf o1, Leaf o2) { return Ints.compare(o1.color, o2.color); } } public class TreeSetTest { public void shouldTestTreeSet() { Leaf leaf = new Leaf(1,1); Leaf leaf2 = new Leaf(1,2); Leaf leaf3 = new Leaf(1,3); Set<Leaf> tree = new TreeSet<Leaf>(new LeafComparator()); tree.add(leaf3); tree.add(leaf); tree.add(leaf2); System.out.println(tree); } }
Tylko leaf3?
OdpowiedzUsuńleaf3, ponieważ metoda 'equals' jest źle zaimplementowana -- zawsze zwraca true.
OdpowiedzUsuńW equals robisz porównanie obj z obj zamiast z obiektem, na którym wywołano equals :)
OdpowiedzUsuńOk, pierwszy babol wypatrzony - nawet szybko. Ale zagadka się nie kończy, co w przypadku jeśli equals będzie poprawnie zaimplementowane?
OdpowiedzUsuńPorównywany jest tylko color, a różnią się size'em?
OdpowiedzUsuńNo tak, to widać na pierwszy rzut oka, pytanie co się dzieje w takim przypadku. Pełnoprawną odpowiedzią jest dopiero taka, która będzie miała dołączone poprawne uzasadnienie. Czekamy dalej...
OdpowiedzUsuńleaf3, ponieważ metoda 'compare' porównuje jedynie color. O ile kontrakt dla Set (z wykorzystaniem equals()) zostanie teraz spełniony, to w TreeSet następuje ponowna weryfikacja w oparciu o compare() co w wypadku obecnego porównania skutkuje takim samym wynikiem jak poprzednia 'błędna' implementacja equals().
OdpowiedzUsuńAnd the winner is msi! Ogólnie w przypadku TreeSet'a dla tego przykładu możemy olać metodę equals i jej w ogóle nie implementować, bo TreeSet używa compare, lub comapreTo, które to muszą być zgodne z equals. Czyli jeśli x.compare(y) == 0, to x.eqals(y) == true. Jak dla mnie słowo zgodne, powinno być czerwonym boldem w dokumentacji, bo dałem się równo nabrać.
OdpowiedzUsuń