2012-01-18 6 views

risposta

7

Bene, dipende dal metodo hashCode() e equals() della classe Pair. Devono ignorare l'ordine.

Set è di per sé un buon esempio di una classe che ignora l'ordine di uguaglianza: è possibile consultare il codice AbstractSet. Se l'ordine della coppia non ha importanza anche al di fuori del confronto di uguaglianza, puoi semplicemente memorizzare HashSet s (ognuno con due elementi) nel tuo set. Sarebbe meglio per avvolgerlo in un tipo di dati:

public class UnorderedPair<T> { 
    private final Set<T> set; 

    public UnorderedPair(T a, T b) { 
      set = new HashSet<T>(); 
      set.add(a); 
      set.add(b); 
    } 

    public boolean equals(Object b) { 
     //...delegate to set 
    } 

    public int hashCode() { 
     return set.hashCode(); 
    } 
} 
+0

sebbene non sia menzionato nell'OP, ciò non funzionerebbe se si tentasse di salvare il set '(a, a)'? – Justin

+1

@Justin: Penso che dipenda dalle tue esigenze. 'new UnorderedPair (a, a) .equals (new UnorderedPair (a, a))' dovrebbe ancora restituire true (l'insieme avrà solo un elemento). Inoltre, 'new UnorderedPair (a, a) .equals (new UnorderedPair (a, null))' dovrebbe restituire false, poiché i null sono ancora voci valide in un 'HashSet'. Personalmente mi piace la variazione di @ erickson di non permettere che all'inizio. –

2

definire una classe Pair cui equals e hashCode metodi sono basati sia su a e b nel modo in cui l'ordine di a e b non importa e utilizzare un HashSet.

0

Ignora i metodi equals() e hashCode() della classe Pair per trattare entrambi (a, b) e (b, a) come uguali.

+1

Anche l'override 'hashCode()' è necessario. –

+0

@ nicholas.hauschild si thats un dato –

+1

Non per qualcuno che non vede come implementare una tupla che può essere usata come una chiave hash. – erickson

3
final class Pair<T> { 
    private final Set<T> elements = new LinkedHashSet<T>(); 
    Pair(T a, T b) { 
    elements.add(a); 
    if (!elements.add(b)) 
     throw new IllegalArgumentException(); 
    } 
    @Override 
    public int hashCode() { 
    return elements.hashCode(); 
    } 
    @Override 
    public boolean equals(Object obj) { 
    if (obj == this) 
     return true; 
    if (!(obj instanceof Pair<?>)) 
     return false; 
    return elements.equals(((Pair<?>) obj).elements); 
    } 
} 
+0

L'uso di un 'Set' significa che' a' e 'b' non possono essere uguali. – Jonathan

+0

Come ho scritto il costruttore, questo non è permesso. Ma se togli il controllo esplicito, 'a' e' b' potrebbero essere lo stesso oggetto, e tutto funzionerebbe ancora. – erickson

+0

Oh, davvero. Buona pesca. Grazie per il chiarimento! – Jonathan