Java 迭代并从地图中删除

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1884889/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 23:33:24  来源:igfitidea点击:

iterating over and removing from a map

java

提问by pstanton

I was doing:

我在做:

for (Object key : map.keySet())
    if (something)
        map.remove(key);

which threw a ConcurrentModificationException, so i changed it to:

抛出了 ConcurrentModificationException,所以我将其更改为:

for (Object key : new ArrayList<Object>(map.keySet()))
    if (something)
        map.remove(key);

this, and any other procedures that modify the map are in synchronized blocks.

这个和任何其他修改映射的过程都在同步块中。

is there a better solution?

有更好的解决方案吗?

if no one comes up with a better solution, first to say no gets the tick ;)

如果没有人想出更好的解决方案,首先说没有就可以了 ;)

采纳答案by noego

As of Java 8 you could do this as follows:

从 Java 8 开始,您可以按如下方式执行此操作:

map.entrySet().removeIf(e -> <boolean expression>);

回答by Paul Tomblin

Use a real iterator.

使用真正的迭代器。

Iterator<Object> it = map.keySet().iterator();

while (it.hasNext())
{
  it.next();
  if (something)
    it.remove();
 }

Actually, you might need to iterate over the entrySet()instead of the keySet()to make that work.

实际上,您可能需要迭代entrySet()而不是keySet()以使其工作。

回答by Alexander Pogrebnyak

You have to use Iteratorto safely remove element while traversing a map.

Iterator在遍历地图时,您必须使用来安全地删除元素。

回答by Gennadiy

Here is a code sample to use the iterator in a for loop to remove the entry.

这是在 for 循环中使用迭代器删除条目的代码示例。

Map<String, String> map = new HashMap<String, String>() {
  {
    put("test", "test123");
    put("test2", "test456");
  }
};

for(Iterator<Map.Entry<String, String>> it = map.entrySet().iterator(); it.hasNext(); ) {
    Map.Entry<String, String> entry = it.next();
    if(entry.getKey().equals("test")) {
        it.remove();
    }
}

回答by Vincent Ramdhanie

Maybe you can iterate over the map looking for the keys to remove and storing them in a separate collection. Then remove the collection of keys from the map. Modifying the map while iterating is usually frowned upon. This idea may be suspect if the map is very large.

也许您可以遍历地图以查找要删除的键并将它们存储在单独的集合中。然后从地图中删除键的集合。在迭代时修改地图通常是不受欢迎的。如果地图非常大,这个想法可能会令人怀疑。

回答by vickirk

An alternative, more verbose way

另一种更详细的方式

List<SomeObject> toRemove = new ArrayList<SomeObject>();
for (SomeObject key: map.keySet()) {
    if (something) {
        toRemove.add(key);
    }
}

for (SomeObject key: toRemove) {
    map.remove(key);
}

回答by goatlinks

I agree with Paul Tomblin. I usually use the keyset's iterator, and then base my condition off the value for that key:

我同意保罗·汤布林的观点。我通常使用键集的迭代器,然后根据该键的值确定条件:

Iterator<Integer> it = map.keySet().iterator();
while(it.hasNext()) {
    Integer key = it.next();
    Object val = map.get(key);
    if (val.shouldBeRemoved()) {
        it.remove();
    }
}

回答by Shishir Kumar

is there a better solution?

有更好的解决方案吗?

Well, there is, definitely, a betterway to do so in a single statement, but that depends on the condition based on which elements are removed.

嗯,肯定有更好的方法在单个语句中执行此操作,但这取决于基于删除哪些元素的条件。

For eg: remove all those elements where valueis test, then use below:

为例如:删除所有这些元素,其中value测试,然后使用以下:

map.values().removeAll(Collections.singleton("test"));

UPDATEIt can be done in a single line using Lambda expression in Java 8.

更新它可以在 Java 8 中使用 Lambda 表达式在一行中完成。

map.entrySet().removeIf(e-> <boolean expression> );

I know this question is way too old, but there isn't any harm in updating the better way to do the things :)

我知道这个问题太老了,但是更新更好的做事方式没有任何害处:)

回答by Aftershock

And this should work as well..

这也应该有效..

ConcurrentMap<Integer, String> running = ... create and populate map

Set<Entry<Integer, String>> set = running.entrySet();    

for (Entry<Integer, String> entry : set)
{ 
  if (entry.getKey()>600000)
  {
    set.remove(entry.getKey());    
  }
}

回答by ROMANIA_engineer

ConcurrentHashMap

并发哈希映射

You can use java.util.concurrent.ConcurrentHashMap.

您可以使用java.util.concurrent.ConcurrentHashMap.

It implements ConcurrentMap(which extends the Mapinterface).

它实现ConcurrentMap(扩展Map接口)。

E.g.:

例如

Map<Object, Content> map = new ConcurrentHashMap<Object, Content>();

for (Object key : map.keySet()) {
    if (something) {
        map.remove(key);
    }
}

This approach leaves your code untouched. Only the maptype differs.

这种方法使您的代码保持不变。只是map类型不同。