2017-08-10 167 views
0

我有一個叫做clientPrinterConnections的multimap,它以多種多樣的方式將打印機名稱映射到SocketConnections。當我關閉SocketConnection時,我想刪除使用它的每個條目。我認爲Multimap實現了ConcurrentMap(它看起來像它在8.0.0中做的,但不是9.0.0),所以我以簡單的方式實現了它。Jetty.util.MultiMap投擲ConcurrentModificationException

for (Map.Entry<String, List<SocketConnection>> e: clientPrinterConnections.entrySet()) { 
     if (e.getValue().contains(connection)) { 
      clientPrinterConnections.removeValue(e.getKey(),connection); 
     } 
    } 

它結束了,不工作,它拋出一個ConcurrentModificationException的。由於需要調用removeValue,我無法真正使用迭代器。

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); 
     } 
    } 

我就可以編譯的事情列出來刪除這個樣子,

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); 
    } 

但似乎凌亂。有沒有更優雅的方式來做到這一點?我可以想象一些僅僅編譯列表的情況不足以解決問題的情況。

+0

注意'ConcurrentModificationException'有使用併發的地圖將不會刪除異常無關,與併發性,即。 – Kayaman

回答

1

由於引發異常的Iterator,所有修改都需要經過它。由於沒有特殊的MultiMapIterator您可以投入使用,編譯刪除列表是您最好的選擇。

0

使用臨時映射,

 Map<String, List<SocketConnection>> tempMap = new HashMap<String, List<SocketConnection>>(); 

     for (Map.Entry<String, List<SocketConnection>> e: clientPrinterConnections.entrySet()) { 
      if (e.getValue().contains(connection)) { 
      tempMap.put(e.getKey(),e.getValue()); 
      } 
     } 

     clientPrinterConnections.clear(); 
     clientPrinterConnections.putAll(tempMap);