Confrontando chiave e i valori di due mappe java

Sono ancora relativamente nuovo per Java e mi sto trovando me stesso bloccato a cercare di scrivere correttamente questo pezzo di codice che mi sento dovrebbe essere un po ‘ più semplice.

Ho due mappe di due diverse istanze dello stesso oggetto. I tasti sono gli oggetti e i valori sono oggetti.

Ci sono due casi, perché sto cercando di determinare se le chiavi in un caso sono diversi dai tasti in un’altra istanza. Sto cercando in particolare di individuare nuove chiavi o tasti mancanti, e poi confrontare i valori delle chiavi, che esistono in entrambe le mappe.

Il codice di esempio qui sotto è solo per aiutare a visualizzare quello che sto cercando di fare (spero di non creare più confusione!)

L’obiettivo di sotto è un esempio che dovrebbe dirmi che il tasto “C” manca e c’è una nuova chiave (“D”) e poi va, infine, confrontare i valori delle chiavi in entrambe le mappe.

Domanda è, esiste un modo per fare questo in un loop? Principalmente perché il mio attuale codice toccare i file di sistema per i valori in mappa e sto cercando di ridurre al minimo i tempi si deve toccare il disco

Map<objA, objB> mapA = new HashMap<objA, objB>();
mapA.put("A", "1");
mapA.put("B", "2");
mapA.put("C", "3");

Map<objA, objB> mapB = new HashMap<objA, objB>();
mapB.put("A", "1");
mapB.put("D", "4");

//Check if something is missing from mapB
for(Map.Entry<objA, objB> entryMapA:mapA.entrySet())
{
    if(!mapB.containsKey(entryMapA.getKey())
        {
            System.out.println(entryMapA.getKey() + " is missing");
        }
}

//Check if something is new is in mapB
for(Map.Entry<objA, objB> entryMapB:mapB.entrySet())
{
    if(!mapA.containsKey(entryMapB.getKey())
    {  
        System.out.println(entryMapB.getKey() + " is new");
    }
}
Questo suona esattamente come Guava è Maps.difference.

OriginaleL’autore hax0r_n_code | 2012-12-25

2 Replies
  1. 9

    Chiavi in Map sono Sets, quindi è possibile utilizzare il set e le operazioni che su di essi.

    Per esempio:

    Set<String> keysInA = new HashSet<String>(mapA.keySet());
    Set<String> keysInB = new HashSet<String>(mapB.keySet());
    
    //Keys in A and not in B
    Set<String> inANotB = new HashSet<String>(keysInA);
    inANotB.removeAll(keysInB);
    
    //Keys common to both maps
    Set<String> commonKeys = new HashSet<String>(keysInA);
    commonKeys.retainAll(keysInB);

    ecc ecc.

    Nota: NON è NECESSARIO utilizzare la chiave di una mappa direttamente. Se volete fare:

    //This returns the actual key set of the map, NOT a copy!
    Set<String> inANotB = mapA.keysSet();
    inANotB.removeAll(mapB.keySet())

    effettivamente rimuovere le chiavi (e i relativi valori associati) in mapA.

    Infine, si dovrebbe notare che HashSet non fa per garantire. Se questo è importante per voi, si vuole guardare a implementazioni di SortedSet (come TreeSet).

    Scusa la mia ignoranza, ma non capisco quando dici “NON è NECESSARIO utilizzare la chiave di una mappa direttamente: è mutevole.” Sono nuovo alla programmazione così alcuni termini sono confuso… ciò che è mutevole?
    il Set restituito da .keySet() è il set di chiavi della mappa. Se si modifica quel set, si modifica la mappa stessa. E probabilmente non si desidera che 😉
    È vero hai bisogno di una copia se si desidera eseguire modifiche distruttive sul set, senza modificare la mappa originale, ma non c’è bisogno di rendere due copie di ciascuno, come il tuo codice. (Mi rendo conto che questo modo ogni variabile è la sua copia.) Questo è un esempio in cui uno stile funzionale (pure le funzioni che restituiscono nuove copie invece di mutatore metodi), come il Guava utilità Louis cita nel commento di cui sopra, conducono ad una più chiara di codice.
    sì, io uso Guava un sacco, ma non l’OP usare? Se si trattasse di me, tutto di Guava dovrebbe essere nel JDK corretto (e così sarebbe Joda Tempo), ma chi sono io per decidere? 😉
    Ho sentito parlare di Guava prima, ma molto onesti, io sono molto nuovo per la programmazione e Java, in modo che io non so nemmeno come utilizzare Guava, in quanto non sembrano essere una parte di standard API.

    OriginaleL’autore fge

  2. 1

    Si può sottrarre il keyset:

    Set<objA> keysA1 = new HashSet<objA>(mapA.keySet()); //deepcopy
    Set<objA> keysA2 = new HashSet<objA>(mapA.keySet()); //deepcopy
    Set<objB> keysB = new HashSet<objB>(mapB.keySet()); //deepcopy
    
    keysA1.removeAll(keysB);
    keysB.removeAll(keysA2);
    
    System.out.println("Missing in A: " + keysB);
    System.out.println("Missing in B: " + keysA1);
    Quasi +1, ma il tuo // deepcopy commenti fuorviante e ingannevole. Il HashSet costruttore fa solo un superficiale copia. Ottenere via con esso qui perché le stringhe sono immutabili, ma se tu avessi oggetti mutabili nel set, tali istanze saranno condivise tra le copie.

    OriginaleL’autore Jiri Kremser

Lascia un commento