2012-05-26 26 views
5

Przeglądam wiele podobnych pytań tutaj i na innych stronach. Nadal nie mogę sprawić, żebym owinął się wokół tego problemu.Metoda przesłaniania równań nie działa

Mam klasy:

public class Event { 
    public String Item; 
    public String Title; 
    public String Desc; 

    @Override 
    public boolean equals(Object o) { 
      return true; 
    } 
} 

próbuję użyć tej klasy w ArrayList<Event> events ale nie mogę znaleźć sposobu na zdobycie events.contains("item") do pracy. Próbowałem debugowania i znalazłem, że nawet nie wchodzi metody zastąpione.

Co robię źle?

+2

Twoja lista zawiera 'Event's, ale wywołujesz' zawiera' z ciągiem znaków. Czy czegoś brakuje? – Tudor

+1

Proszę pokazać kod, w którym wypełniasz listę i wywołujesz 'zawiera'. – Tudor

Odpowiedz

7

To dlatego, że łamiesz symetrię jak specified in the contract z equals(): jeśli każde zdarzenie jest równa "item" (który jest ciągiem), "item" powinny być również równe każdym razie.

Właściwie to, co robi Java, to wywołać indexOf("item") na liście i sprawdzić, czy jest pozytywna.

Teraz indexOf() działa jak to w ArrayList na przykład (patrz complete source code here):

for (int i = 0; i < size; i++) 
     if ("item".equals(elementData[i])) 
      return i; 

Więc w zasadzie jest to metoda String's equals() który nazywa się tutaj, a nie taki, który jest Twój powrót fałszywe oczywiście.

rozwiązać ten problem, po prostu określając parametr Event do funkcji, takich jak:

events.contains(new Event("item", "title", "desc")) 

Zauważ, że musisz utworzyć odpowiedni konstruktor klasa ot zainicjować członków.

+0

Jak mogę to rozwiązać? – CornflakesDK

+1

Wreszcie dobra odpowiedź. Ze względu na kompletność możesz połączyć i/lub opublikować kod źródłowy pliku "ArrayList.contains": http://www.docjar.com/html/api/java/util/ArrayList.java.html – Tudor

+1

@CornflakesDK: Możesz zacząć od porównywania jabłek z pomarańczami. Wyszukaj na liście 'Event', ponieważ zawiera' Event's. – Tudor

0

Należy również zastąpić public int hashCode(). Te dwie metody są ze sobą ściśle powiązane.

Czytaj więcej na ten temat: http://www.javapractices.com/topic/TopicAction.do?Id=17

+1

OP używa właśnie 'ArrayList'. Chociaż ta odpowiedź jest prawdziwa, nie jest to pomocne. –

+1

Nie, hashCode() nie ma nic do czynienia z tym. Dzieje się tak, ponieważ symetria jest zepsuta. – rlegendi

0

Kiedy zastąpić equals() metody, trzeba też zastąpić metodę hashcode() ponieważ idą w parze. Jeśli dwa obiekty są równe, muszą mieć ten sam kod skrótu. Hashmaps używa tego do oceny lokalizacji zapisu. Jeśli dwa obiekty nie są równe, mogą mieć lub nie mieć ten sam kod skrótu.

0

W tym przypadku potrzebna jest tylko metoda override equals, a nie metoda hashCode.

Metoda hashCode i equals powinny zostać nadpisane, jeśli chcesz użyć obiektu klasy jako klucza w HashMap. HashMap używa struktury array + linkedList. Podczas dodawania pary klucz-wartość najpierw należy wykonać pewne obliczenia na podstawie parametru hash klucza, aby uzyskać indeks w tablicy; następnie przejdź przez linkList na tej pozycji indeksu, aby sprawdzić, czy para klucz-wartość już tam jest. Jeśli tak, nadpisze rekord z nową wartością; w przeciwnym razie dodaj parę klucz-wartość na końcu tej listy połączonej. Podczas lokalizowania klucza proces jest łatwiejszy. Więc jeśli metoda hashCode nie zostanie nadpisana, nie powiedzie się wyszukiwanie w pierwszej rundzie w tablicy. To jest powód, dla którego potrzebujesz zastąpić obie metody. Nie jest tak, że gdzieś jest powiedziane, że istnieje kontrakt między tymi dwiema metodami lub mają one bliski związek.

Powiązane problemy