I have a multimap called clientPrinterConnections that maps printer names to SocketConnections in a many to many manner. When I close a SocketConnection, I want to remove every entry that uses it. I thought Multimap implements ConcurrentMap (it seems like it did in 8.0.0 but not 9.0.0) so I did it the easy way.
for (Map.Entry<String, List<SocketConnection>> e: clientPrinterConnections.entrySet()) {
if (e.getValue().contains(connection)) {
clientPrinterConnections.removeValue(e.getKey(),connection);
}
}
It ends up that doesn't work, and it throws a ConcurrentModificationException. I can't really use an iterator though due to needing a removeValue call.
Iterator iter = clientPrinterConnections.entrySet().iterator();
while(iter.hasNext()) {
Map.Entry<String, List<SocketConnection>> pair = (Map.Entry)iter.next();
if (pair.getValue().contains(connection)) {
//this deletes all connections to the specific printer
iter.remove();
//this throws the same exception as before
clientPrinterConnections.removeValue(pair.getKey(),connection);
}
}
I can just compile a list of things to delete like this,
ArrayList<String> itemsToDelete = new ArrayList();
for (Map.Entry<String, List<SocketConnection>> e: clientPrinterConnections.entrySet()) {
if (e.getValue().contains(connection)) {
itemsToDelete.add(e.getKey());
}
}
for (String s: itemsToDelete){
clientPrinterConnections.removeValue(s,connection);
}
but that seems messy. Is there a more elegant way to do this? I can imagine some situations where just compiling a list wouldn't be an adequate fix.