[W czasie pisania tego tekstu opublikowano trzy inne odpowiedzi.]
Powtarzam, celem mojego pytania jest znalezienie standardowych przypadków testów, które to potwierdzą hashCode
i equals
zgadzają się ze sobą. Moje podejście do tego pytania polega na wyobrażeniu sobie wspólnych ścieżek, którymi kierują się programiści pisząc omawiane klasy, a mianowicie niezmiennych danych. Na przykład:
- Napisałem
equals()
bez pisania hashCode()
. To często oznacza, że równość była definiowana jako równość pól dwóch instancji.
- Napisałem
hashCode()
bez pisania equals()
. Może to oznaczać, że programista szukał wydajniejszego algorytmu mieszającego.
W przypadku # 2 wydaje mi się, że problem nie istnieje. Nie utworzono equals()
żadnych dodatkowych instancji, więc żadne dodatkowe instancje nie muszą mieć równych kodów skrótów. W najgorszym przypadku algorytm wyznaczania wartości skrótu może dawać gorszą wydajność w przypadku map skrótów, co jest poza zakresem tego pytania.
W przypadku # 1 standardowy test jednostkowy polega na utworzeniu dwóch wystąpień tego samego obiektu z tymi samymi danymi przekazanymi do konstruktora i sprawdzeniu równych kodów skrótów. A co z fałszywymi alarmami? Możliwe jest wybranie parametrów konstruktora, które po prostu dają równe kody skrótu w mimo to niesprawnym algorytmie. Test jednostkowy, który ma tendencję do unikania takich parametrów, byłby zgodny z duchem tego pytania. Skrótem tutaj jest equals()
zbadanie kodu źródłowego , przemyślenie i napisanie testu opartego na tym, ale chociaż może to być konieczne w niektórych przypadkach, mogą również istnieć popularne testy, które wychwytują typowe problemy - i takie testy również spełniają ducha tego pytania.
Na przykład, jeśli testowana klasa (nazwij ją Data) ma konstruktor, który pobiera String i instancje zbudowane z ciągów, które są equals()
zwracanymi instancjami, które były equals()
, wtedy dobry test prawdopodobnie przetestowałby:
new Data("foo")
- inne
new Data("foo")
Moglibyśmy nawet sprawdzić kod skrótu new Data(new String("foo"))
, aby wymusić na String, aby nie był internowany, chociaż Data.equals()
moim zdaniem jest to bardziej prawdopodobne, że dostarczy poprawny kod skrótu, niż daje poprawny wynik.
Odpowiedź Eli Courtwright jest przykładem intensywnego zastanawiania się nad sposobem złamania algorytmu wyznaczania wartości skrótu w oparciu o znajomość equals
specyfikacji. Przykład specjalnej kolekcji jest dobry, ponieważ Collection
czasami pojawiają się pliki utworzone przez użytkownika i są one dość podatne na muckupy w algorytmie haszującym.