2015-10-20 93 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