2012-12-08 35 views
5

Po raz pierwszy używam tej strony, więc przepraszam, jeśli nie używam jej poprawnie. Proszę, daj mi znać.Przesłanianie hasłem

W każdym razie mam obiekt konta, który przyjmuje 2 ciągi ... Nazwa funkcji i nazwisko (kod jest poniżej).

Chcę wstawić ten obiekt do tabeli mieszania z kluczem będącym acctName i chciałbym użyć wielomianów do zmniejszenia kolizji. Słyszałem, że muszę przesłonić hashCode() i równe metody. Uważam, że nadpisałem poprawnie, ale nie jestem pewien, czy jest poprawny, ponieważ wydaje się, że nie został wywołany. Czy ktoś może mi powiedzieć, czy robię to dobrze (przesłonięcie we właściwym miejscu i dodanie poprawnie) i wyjaśnić mi, jak wydrukować po dodaniu?

Dziękuję i czekam na wkład w rozwój społeczności w przyszłości!

Klasa ---> konta

public class Account 
{ 

private String acctName; 
private String lastName; 

public Account(String acctName, String lastName) 
    { 
    this.acctName= acctName; 
    this.lastName= lastName 
    } 

@Override 
public int hashCode() { 

    return acctName.hashCode() + lastName.hashCode(); 

} 

@Override 
public boolean equals (Object otherObject) { 
    if (!(otherObject instanceof Account)) { 
     return false; 
    } 
    if (otherObject == this) { 
     return true; 
    } 

    Account accountHolder = (Account) otherObject; 
    return acctName.equals(accountHolder.acctName) && lastName.equals(accountHolder.lastName); 
} 

Klasa ----> Driver

public void insertInto() 
{ 
Hashtable<String,Account> hash=new Hashtable<String,HoldInformation>(); 
Account account= new Account ("Deposit", "Jones"); 
Account account2= new Account ("Withdraw", "Smith"); 


hash.put ("deposit", account); 
hash.put ("Withdraw", account2); 

} 

EDIT Z Getter INSIDE obiekt konta

public String testGetter() 
    { 

    return acctName.hashCode() + lastName.hashCode(); 
    } 

Odpowiedz

1

HashCode pola klucza służy do mieszania. Używasz ciągu znaków jako klucza, a dla kodu niestandardowego kodu wynikowego. dlatego nie została wywołana.

+0

Ah sens, moim problemem jest to, że moje konto przedmiot trwa acctName i nazwisko w jednym obiekcie. Jak już powiedziałem, kluczem jest acctName. Więc co mógłbym użyć dla pola klucza podczas deklarowania hashtable, jeśli mam wszystko, czego potrzebuję w obiekcie mojego konta? – michael

+0

Czy powinienem umieścić wszystko w obiekcie konta zamiast w sterowniku? Dzięki! – michael

+0

dodaj metodę getter do klasy, która zwróci "" acctName.hashCode() + lastName.hashCode(); "". ANd następnie użyj zwróconej wartości jako klucza tablicy hashtable. –

0

Robisz kilka rzeczy, które nie robią tego, co myślisz. Używasz String jako klucza, który nie jest związany z twoim obiektem. Nie ma znaczenia, że ​​jest to ten sam ciąg, którego chcesz używać jako nazwy konta (co w rzeczywistości nie jest spowodowane twoją wielką literą), ale także nadpisujesz obiekty w Hashmapie, używając tego samego klucza dwa razy (jesteś hasmapem nie będzie już przechowywać konta, tylko konto3).

Wygląda na to, że chcesz użyć zestawu zamiast mapy.

+0

Dziękuję za odpowiedź palako ... Zajrzę do mapowania, ale na razie możemy po prostu zignorować, że dwukrotnie miałem ten sam klucz? do celów edukacyjnych ... załóżmy, że to nie był ten sam klucz. Dokonaj edycji – michael

+0

, jeśli nie będziesz mieć duplikacji acctName i chcesz użyć go jako klucza do mapy, a następnie po prostu wykonaj hash.put (account.getAcctName(), account); i nie trzeba przesłonić równych lub hashcode. Jeśli uważasz, że masz duplikaty, a nie potrzebujesz klucza, zachowaj równe i hashcode i użyj zestawu, zrobi to samo co mapa, ale bez klucza i uniemożliwi dups. – palako

0

Jeśli nie masz żadnych zduplikowanych nazw kont, możesz użyć nazwy każdego konta jako klucza mapy.

Twój hashCode() metoda nie nazywa, bo nie używasz obiektów konta jako klucz: używasz strun.

Oto w jaki sposób można umieścić konto na mapie używając jego ACCOUNTNAME:

Account accountOne = new Account("checking", "Smith"); 
Account accountTwo = new Account("saving", "Jones"); 

Map<String, Account> accountMap = new HashMap<String, Account>(); 

accountMap.put(accountOne.getAcctName(), accountOne); 
accountMap.put(accountTwo.getAcctName(), accountTwo); 

Pamiętaj, że masz do wdrożenia Account.getAccntName(), która będzie wyglądać następująco:

public String getAccttName() { 
    return acctName; 
} 

Nawiasem mówiąc, wygląda na to zrobiłeś dobrą robotę unieważniając hashCode() i equals().

I ... zapraszamy do StackOverflow.

+0

Dzięki jahroy! Po prostu zastanawiam się na podstawie twojego kodu ... czy twoja wersja nadal używa hashTables ... jest jak HashMap? – michael

+0

O tak ... oops. Użyłem HashMap z przyzwyczajenia. Implementacja powinna być identyczna dla Hashtable (obie implementują mapę). – jahroy

+0

Bez obaw Dziękujemy. Ale moje metody nadpisywania nie wydają się być wywoływane. Każdy pomysł, dlaczego? – michael

0

Próbowałem follwinf. Ale kompilator nie pokazuje niczego złego !!!!

test pakietu;

import java.util.Hashtable; 

public class Account { 
private String acctName; 
private String lastName; 

public Account(String acctName, String lastName) 
    { 
    this.acctName= acctName; 
    this.lastName= lastName; 
    } 

@Override 
public int hashCode() { 

    return acctName.hashCode() + lastName.hashCode(); 

} 

@Override 
public boolean equals (Object otherObject) { 
    if (!(otherObject instanceof Account)) { 
     return false; 
    } 
    if (otherObject == this) { 
     return true; 
    } 

    Account accountHolder = (Account) otherObject; 
    return acctName.equals(accountHolder.acctName) && lastName.equals(accountHolder.lastName); 
} 

public String testGEtter() 
{ 
    return lastName+","+acctName; 
} 

public static void mian(String args[]) 
{ 
    Hashtable<String , Account> table = new Hashtable<>(); 
    Account acc= new Account("test1", "test2"); 
    table.put(acc.testGEtter(), acc); 
} 

}

+0

To też działa dla mnie ... w porządku ostatnie pytanie, bo nie chcę ci więcej przeszkadzać ... :) Jak ten kod różni się od mojego wcześniej (oryginalna? Jedyną różnicą jest to, że użyłeś gettera dla klucza i ja Powiedziałeś na samym początku, że nie została wywołana metoda override, ponieważ mój klucz był ciągiem, a nadpisanie wciąż nie jest wywoływane ... – michael

+0

ok. na początku dzwoniłeś z tym ---- - "hash.put (" depozyt ", konto);" " spójrz na ciąg" depozytu ", klasa string ma własną funkcję toHashcode, więc twoja implementacja hashCode w klasie Konto nie będzie używana do mieszania. Funkcja toHashcode obiektu używanego jako klucz jest używana dla hasihing, a zarówno nazwisko, jak i nazwa nie były używane dla klucza, to była główna różnica, ale kiedy wywołujesz z "" table.put (acc.testGEtter(), acc) ; "" "ten --- jeden łączy twoje oba pola nazwy i używa t kapelusz połączony ciąg jest kluczem. –

0

hashmap realizuje hashCode() wykonanie obliczania hashcode od przedmiotu który ma być używany jako klucza hashmap.

Wygląda na to, że z Twojego kodu chcesz odwzorować nazwy użytkowników na odpowiednie konta. W takim przypadku nadpisywanie hashCode() i equals() jest bezużyteczne.

Uwaga: hashCode() dla obiektu będzie używany tylko wtedy, gdy obiekt jest używany jako klucz. W twoim przypadku do haszowania w mapie używana jest klasa hash.lang.String klasy hashCode().

  • Warunki hashCode i równa

    1. Ilekroć jest wywoływane na tym samym obiekcie więcej niż jeden raz w trakcie wykonywania aplikacji Java, metoda hashCode musi konsekwentnie zwracają taką samą liczbą całkowitą, nie przewidziane informacje używane w porównywaniu równań na obiekcie są modyfikowane. Ta liczba całkowita nie musi pozostawać spójna od jednego wykonania aplikacji do innego wykonania tej samej aplikacji.

    2. Jeśli dwa obiekty są równe zgodnie z metodą equals (Object), wówczas wywołanie metody hashCode na każdym z dwóch obiektów musi dać taki sam wynik całkowity.

    3. Za każdym razem, gdy zastępujesz metodę equals(), musisz również przesłonić metodę hashCode().