2012-12-08 15 views
5

Questa è la mia prima volta che uso questo sito, quindi mi scuso se non lo sto usando correttamente. Per favore fatemi sapere.Sovrascrittura hash

In ogni caso, ho un oggetto Account che accetta 2 stringhe ... Un acctName e lastName (il codice è sotto).

Voglio inserire questo oggetto in una tabella hash con la chiave come acctName e vorrei usare i polinomi per ridurre la collisione. Ho sentito che devo scavalcare hashCode() e metodo uguale. Credo di averlo scavalcato correttamente ma non sono sicuro che sia corretto perché sembra non essere chiamato. Qualcuno può dirmi se sto facendo questo correttamente (Override nella giusta posizione e aggiungendo correttamente) e spiegami come stampare dopo un add?

Grazie e non vedo l'ora di contribuire alla comunità in futuro!

Class ---> Account

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); 
} 

Class ----> 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); 

} 

Modifica con GETTER ALL'INTERNO account oggetto

public String testGetter() 
    { 

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

risposta

1

Il codice hash del campo chiave viene utilizzato per l'hashing. Stai usando string come chiave e implementando hashcode per la tua classe personalizzata. è per questo che non è stato chiamato.

+0

Ah ha un senso, il mio problema è che il mio oggetto account prende acctName e cognome in un unico oggetto. Come ho detto, l'acctName è la chiave. Quindi cosa posso usare per il campo chiave quando dichiaro l'hashtable se ho tutto ciò di cui ho bisogno all'interno dell'oggetto Account? – michael

+0

O dovrei inserire tutto nell'oggetto Account anziché nel driver? Grazie! – michael

+0

aggiungi un metodo getter nella tua classe per cui verrà restituito "" acctName.hashCode() + lastName.hashCode(); "". Quindi utilizzare il valore restituito come chiave della tabella hash. –

0

Stai facendo un paio di cose che non fanno quello che pensi. Stai utilizzando una stringa come chiave non correlata al tuo oggetto. Non importa che sia la stessa stringa che vuoi usare come nome account (che in realtà non è a causa della tua maiuscola), ma stai anche sovrascrivendo gli oggetti in Hashmap usando la stessa chiave due volte (sei hasmap non memorizzerò più account, solo account3).

Mi sembra che si desideri utilizzare un set anziché una mappa.

+0

Grazie per la risposta palako ... guarderò nella mappatura ma per ora possiamo semplicemente ignorare che ho avuto la stessa chiave due volte? per scopi di apprendimento ... supponiamo che non fosse la stessa chiave. Modifica apportata – michael

+0

se non si hanno duplicazioni in acctName e si desidera utilizzarlo come chiave per la mappa, quindi eseguire hash.put (account.getAcctName(), account); e non è necessario sovrascrivere equals o hashcode. Se pensi di avere duplicati, e non hai bisogno della chiave, mantieni i tuoi equals e hashcode e usi un Set, farà la stessa cosa della mappa ma senza la chiave e ti impedirà di avere i duplicati. – palako

0

Se non si dispone di nomi di account duplicati, è perfettamente corretto utilizzare il nome di ciascun account come chiave della mappa.

Il tuo hashCode() metodo non viene chiamato perché non stai utilizzando oggetti Account come chiave: stai utilizzando Stringhe.

Ecco come si sarebbe messo un conto nella mappa utilizzando il suo 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); 

noti che dovrete implementare Account.getAccntName(), che sarebbe simile a questa:

public String getAccttName() { 
    return acctName; 
} 

Tra l'altro, sembra che hai fatto un buon lavoro sovrascrivendo hashCode() e equals().

E ... benvenuto su StackOverflow.

+0

Grazie jahroy! Mi chiedo solo in base al tuo codice ... la tua versione usa ancora hashTables ... è come HashMap? – michael

+0

Oh sì ... oops. Ho usato HashMap per abitudine. L'implementazione dovrebbe essere identica per Hashtable (entrambi implementano Map). – jahroy

+0

Nessun problema Grazie. Ma i miei metodi di override non sembrano essere chiamati. Qualche idea del perché? – michael

0

Ho provato il follwinf. Ma il compilatore non mostra niente di sbagliato !!!!

test del pacchetto;

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

Funziona anche per me ... okay domanda finale perché non voglio disturbarti più ... :) Come è diverso questo codice dal mio prima (originale? L'unica differenza è che hai usato un getter per la chiave e io Si è detto all'inizio che la ragione per cui il metodo di override non è stato chiamato è perché la mia chiave era una stringa e l'override non viene ancora chiamato ... – michael

+0

ok, all'inizio chiamavi con questo ---- - "" "hash.put (" deposito ", account);" " esaminare la stringa" deposito ", la classe stringa ha la propria funzione toHashcode. Pertanto l'implementazione hashCode all'interno della classe Account non verrà utilizzata per l'hashing. La funzione toHashcode dell'oggetto usato come chiave viene utilizzata per l'hashing e sia il cognome che il nome acct non sono stati utilizzati per il hasing, questa era la differenza principale, ma quando si chiama con "" table.put (acc.testGEtter(), acc) ; "" "questo --- uno combina il tuo campo di entrambi i nomi e usa t hat concatenated string a s the key. –

0

Il hashmap implementa l'attuazione hashCode() per calcolare il codice hash dall'oggetto da utilizzare come chiave nella hashmap.

Dal codice, sembra che si desidera mappare i nomi utente agli account corrispondenti. In tal caso, l'override hashCode() e equals() non è di alcuna utilità.

Nota: hashCode() per un oggetto verrà utilizzato solo se l'oggetto viene utilizzato come chiave. Nel tuo caso, hashCode() della classe java.lang.String viene utilizzata per l'inserimento nella mappa hash.

  • Condizioni per hashCode e uguale

    1. Ogniqualvolta viene richiamato sullo stesso oggetto più di una volta durante un'esecuzione di un'applicazione Java, il metodo hashCode deve sempre restituire lo stesso numero intero, a condizione che non le informazioni utilizzate nei confronti di pari merito sull'oggetto sono modificate. Questo numero intero non deve rimanere coerente da un'esecuzione di un'applicazione a un'altra esecuzione della stessa applicazione.

    2. Se due oggetti sono uguali secondo il metodo equals (Object), quindi chiamando il metodo hashCode su ciascuno dei due oggetti devono produrre lo stesso risultato intero.

    3. Ogni volta che si esegue l'override del metodo equals(), è necessario sovrascrivere anche il metodo hashCode().