2009-04-27 12 views
7

Voglio rendere una classe utilizzabile in SortedSet | SortedMap.Ha senso per uguali e confronti Per essere incoerente?

class MyClass implements Comparable<MyClass>{ 
    // the only thing relevant to comparisons: 
    private final String name; 

    //... 
} 

Le istanze della classe devono essere ordinate in base alla relativa proprietà.
Tuttavia, non voglio che le istanze con lo stesso nome siano considerate uguali.

Quindi un contenuto di SortedSet sarà simile a a, a, a, b, c.
(Normalmente, SortedSet avrebbe consentito solamente a, b, c)

Innanzitutto: è questo (filosoficamente) consistente?

Se è così, devo aspettare un comportamento imprevedibile, quando lo faccio non esclusione equals(...) e hashCode()?

Edit:
Mi dispiace, la mia domanda sembra incoerente:
Voglio mettere più "uguale" valori all'interno di un set , che non consente questo dal concept.
Quindi, per favore non rispondere più alla mia domanda.
Grazie a tutti coloro che hanno già risposto.

+0

Perché non utilizzare solo un tipo di raccolta diverso? –

+0

Sì, MultiSet dell'API di google-collection | MultiMap sembra buono per questo. Spero tanto che il Sun, aehm, Oracle ragazzi un giorno aggiungerebbe funzionalità all'API di raccolta Java ... –

risposta

18

Lascia che ti faccia una domanda: ha senso avere a.compareTo(b) restituire 0 e a.equals(b) restituire false?

Vorrei utilizzare un Comparator<MyClass> invece. Questo è il motivo per cui tutte le implementazioni SortedMap/SortedSet che conosco consentono di passare in un Comparator alla creazione.

+0

Tenderei a rispondere: non ha senso;) Grazie, ho dimenticato che c'è qualcosa come un comparatore;) –

+0

Domanda giusta. – Joshua

2

Effective Java raccomanda che se non implementare compareTo coerente con equals si dovrebbe indicare chiaramente così:

La lingua consigliata è "Nota: Questa classe ha un ordinamento naturale che è incompatibile con eguali. "

0

Basta mettere questo codice nel metodo equals e non lo mai pensato di nuovo:

public boolean equals(Object obj) { 
    if (this == obj) return true; 
    if (!(obj instanceof MyClass)) return false; 
    return 0 == this.compareTo((MyClass) obj); 
} 
+0

Ma se si implementa equals(), è necessario implementare anche hashcode(). Altrimenti possono succedere cose strane. –

+0

È possibile delegare hashCode a un'altra proprietà o un metodo che restituisce un valore int paragonabile. Ma non preoccupatevi, dal momento che hashCode è come controllare se ha lo stesso riferimento, non se hanno lo stesso valore. – Azder

4

Dal Javadoc per Paragonabile

Si raccomanda vivamente (anche se non richiesto) che gli ordinamenti naturali siano coerenti con gli uguali.Questo è così perché insiemi ordinati (e ordinati mappe) senza comparatori espliciti comportano "stranamente" quando vengono utilizzati con elementi (o chiavi) la cui ordinamento naturale è incompatibile con uguale

Se vuoi avere un confronto Per quanto sia incoerente con equals(), si consiglia di utilizzare un comparatore esplicito, fornendo una classe che implementa Comparator.

Se è così, devo aspettare un comportamento imprevedibile, quando non sovrascrive equals (...) e hashCode()?

Si dovrebbe comunque eseguire l'override di equals() e hashcode(). Indipendentemente dal fatto che equals() e hashcode() siano coerenti con compareTo è una questione diversa.

Problemi correlati