Modifica simultanea di due Set <String> da parte di keepAll

Sep 29 2020

Ho bisogno di come modificare il set durante l'iterazione di keepAll

Diciamo che ho il prossimo codice:

set.forEach(it - > {
    set.retainAll(someMapWithSets.get(it))
});

Ho provato l'approccio con gli iteratori:

for (Iterator<String> iterator = set.iterator(); iterator.hasNext();) {
    String value = iterator.next();
    set.retainAll(someMapWithSets.get(value))
}

Non ha funzionato. ConcurrentModificationExceptionè stato gettato.

Come farlo correttamente?

Aggiornare.

L'intero compito è il prossimo: 

Ho impostato

{A,B,C}

E ho una mappa di insiemi che indica se gli elementi sono compatibili:

A: B,C - (means A is compatible with B and C and etc) 
B: A,E,C
C: A,B

Ho bisogno di una mappa dei set in cui siano presenti tutte le possibili combinazioni di elementi compatibili:

A,B,C

Così come parte della soluzione ho pensato di poter creare un metodo che conservi solo gli elementi compatibili per l'insieme dato e l'elemento scelto.

 public static Set<String> define(Set<String> elements, String rootElement) {
        Set<String> result = someMapWithElements.get(rootElement);
        result.retainAll(elements);
        result.add(rootElement);
        result.forEach(it -> result.retainAll(someMapWithElements.get(it)))
        return result;
    }

Ma ovviamente capisco ConcurrentModificationException

Risposte

1 tb189 Sep 29 2020 at 17:35

Non è possibile modificare un set utilizzando il retainAllmetodo durante l'iterazione sullo stesso oggetto. Pertanto dovrai creare un nuovo set (o altra raccolta) da utilizzare come variabile di iterazione, come:

new HashSet(set).forEach(it - > {
    set.retainAll(someMapWithSets.get(it))
});

HashSetpuò essere sostituito da TreeSeto da qualsiasi altro oggetto impostato adatto.

Se effettivamente è necessario modificare il set durante l'iterazione, sarà necessario utilizzare il removemetodo in Iterator.