Memorizzazione di coppie in una mappa

6

Se ho una classe Pair come questa:

class Pair<K, L>{
   public final K a;
   public final L b;


   public Pair(K obj1, L obj2){this.a = obj1; this.b = obj2;}
   //...
}

Voglio associare un Float a ogni coppia di oggetti. Sono dello stesso tipo, quindi l'oggetto Pair sarà Pair<SomeType, SomeType> . È abbastanza naturale inserirli in Map<Pair<SomeType, SomeType>, Float> .

Il fatto è che non voglio che l'ordine degli oggetti in questa coppia sia importante. Voglio dire, una volta inserito un Pair<SomeType, SomeType> myPair tale che myPair.a = obj1 , myPair.b = obj2 nella Mappa, mi piacerebbe essere in grado di recuperare lo stesso valore con l'oggetto Pair invertito, tale che a = obj2 , b = obj1 .

Va bene inserire due coppie sulla mappa in entrambi gli ordini in questo caso, ovvero new Pair(a, b) e new Pair(b, a) ? In questo modo sono sicuro che indipendentemente da come gli oggetti sono ordinati nella coppia, otterrò il valore corretto. Tuttavia ci vuole il doppio spazio e crea problemi quando si tenta di rimuovere una coppia chiave-valore dalla mappa (ho bisogno di rimuovere entrambi). Forse è bello creare un metodo che si occuperà di inserire e rimuovere entrambe le coppie dalla mappa?

    
posta user4205580 03.04.2016 - 22:11
fonte

1 risposta

5

Se Map è HashMap , utilizzerà i metodi Pair hashCode() e equals() per determinare l'uguaglianza. Questi metodi possono essere sovrascritti. La parte importante è assicurarsi che l'ordine degli articoli non sia importante. Per hashCode() , questo può essere ottenuto mediante xoring dei codici hash degli elementi pair. Per equals() , gli elementi devono essere uguali a coppie o uguali a coppie quando capovolti.

class UnorderedPair<A> {
  public final Pair<A, A> pair;
  ...

  @Override int hashCode() { return pair.a.hashCode() ^ pair.b.hashCode(); }

  @Override boolean equals(Object o) {
    ...
    UnorderedPair<A> other = (UnorderedPair<A>) o;
    return (a.equals(other.a) && b.equals(other.b))
        || (a.equals(other.b) && b.equals(other.a));
  }
}

Utilizzeresti quindi un Map<UnorderedPair<SomeType>, Float> . Ciò richiede di avvolgere ogni Pair in un altro oggetto per fornire l'uguaglianza personalizzata, ma trovo che sia più pulito della sottoclasse, dato che decoriamo una coppia con la nuova semantica dell'uguaglianza ai fini della tua% codice%. Se crei metodi aggiuntivi per le operazioni di inserimento / eliminazione della tua mappa, verranno solo avvolgere / scartare il dato Map in Pair .

    
risposta data 03.04.2016 - 22:28
fonte

Leggi altre domande sui tag