2015-10-20 154 views
1

我hava一個SortedMap<Long, List<MyType>>,我想刪除List<MyType>,如果List<MyType>是空的,我也將刪除Long鍵。迭代SortedMap刪除條目

在Java 8中有一個優雅的解決方案嗎?使用此代碼我得到ConcurrentModificationException

SortedMap<Long, List<MyType>> dates = ... 

for (final Long key : this.getDates().keySet()) { 
    for (final Iterator<MyType> iterator = this.getDates().get(key).iterator(); 
     iterator.hasNext();) { 
    final MyType myType= iterator.next(); 
    if (myType.getMarker().intValue() == marker.intValue()) { 
     iterator.remove(); 

     if (this.getDates().get(key).isEmpty()) { 
     this.getDates().remove(key); 
     } 
     break; 
    } 
    } 
} 

回答

2

第一位可以寫爲:

for (List<MyType> list : dates.values()) { 
    list.removeIf(myType -> myType.getMarker().intValue() == marker.intValue()); 
} 

和第二位可以寫成:

dates.values().removeIf(List::isEmpty); 

這需要兩遍,但是,在我看來,更容易理解(並且性能影響可能很小)。


替代於迭代:

for (Iterator<List<MyType>> it = dates.values().iterator(); it.hasNext();) { 
    List<MyType> list = it.next(); 
    list.removeIf(myType -> myType.getMarker().intValue() == marker.intValue()); 
    if (list.isEmpty()) it.remove(); 
} 
0

你可以重複在地圖上的條目。對於每個條目,您可以使用嵌套迭代器刪除匹配值。最後,刪除該條目值列表爲空:

Iterator<Entry<String, List<Integer>>> entryIterator = map.entrySet().iterator(); 
    while (entryIterator.hasNext()) { 
     Entry<String, List<Integer>> entry = entryIterator.next(); 
     Iterator<Integer> iterator = entry.getValue().iterator(); 
     while (iterator.hasNext()) { 
      Integer value = iterator.next(); 
      if (Objects.equal(value, marker)) { 
       iterator.remove(); 
      } 
     } 
     if (entry.getValue().isEmpty()) { 
      entryIterator.remove(); 
     } 
    } 
+1

有趣的是,你替換'MyType'逃走了與'整數'。我想知道這些調用原始代碼的'intValue()'調用是否真的有必要,但是我也不會想到''getMarker()'調用。如果值對象真的是一個'List ',一個簡單的'entry.getValue()。removeAll(singleton(marker))'就足夠了...... – Holger

+0

@Holger當然。我只想展示如何使用迭代器正確刪除。 II使用Integer是因爲編寫基本程序更簡單。 – gontard

2

在Java 8個集現在有一個removeIf()方法,你可以利用:

getDates().values().forEach(list -> list.removeIf(myType -> myType.getMarker().intValue() == marker.intValue())); 
getDates().values().removeIf(List::isEmpty); 
+0

偉大的解決方案 - 非常感謝! – quma