如何有效地从 Java 中的 LinkedHashMap 中删除条目?
How to efficiently remove entries from a LinkedHashMap in Java?
我想从 LinkedHashMap 中删除在具有给定键的条目之后添加的所有条目。
我的第一次尝试是:
LinkedHashMap<String, SomeObject> var = new LinkedHashMap<String, SomeObject>();
public void removeEntriesAfter(String key) {
boolean deleteEntries = false;
for (String currentKey : var.keySet()) {
if(deleteEntries) {
var.remove(currentKey);
} else {
if(key.equalsIgnoreCase(currentKey)) {
// Do not remove the current entry
deleteEntries = true;
}
}
}
}
但后来我收到了 java.util.ConcurrentModificationException
。
我的第二个想法是先确定密钥,然后再删除它们。
public void removeEntriesAfter(String key) {
boolean deleteEntries = false;
List<String> listOfEntriesToBeRemoved = new ArrayList<String>();
// Determine entries to be deleted
for (String currentKey : var.keySet()) {
if(deleteEntries) {
listOfEntriesToBeRemoved.add(currentKey);
} else {
if(key.equalsIgnoreCase(currentKey)) {
// Do not remove the current entry
deleteEntries = true;
}
}
}
// Removed selected entries
for (String currentKey : listOfEntriesToBeRemoved) {
var.remove(currentKey);
}
}
这行得通,但我相信还有更多 elegant/efficient 方法可以做到这一点。
要避免 ConcurrentModificationException
,您可以使用 Iterator
。
Iterator<String> it = map.keySet().iterator();
while (it.hasNext())
if (it.next().equalsIgnoreCase(currentKey))
break;
while (it.hasNext()) {
it.next();
it.remove();
}
如果您想要最 有效的解决方案,首先是直接进入适当的条目。为此,您只需将小写键放入映射中(而不是放入任何旧字符串并使用 equalsIgnoreCase
进行比较)。然后,使用反射,您可以访问对应于 currentKey.toLowerCase()
的 Map.Entry
对象,然后再次使用反射,您可以在地图中一直跟踪链接。 None 无需反射即可实现,因为与键对应的条目和条目之间的链接都不会通过 public API 公开。我不建议反射,因为如果更改 LinkedHashMap
的代码,您的代码将来很容易中断。
我想从 LinkedHashMap 中删除在具有给定键的条目之后添加的所有条目。
我的第一次尝试是:
LinkedHashMap<String, SomeObject> var = new LinkedHashMap<String, SomeObject>();
public void removeEntriesAfter(String key) {
boolean deleteEntries = false;
for (String currentKey : var.keySet()) {
if(deleteEntries) {
var.remove(currentKey);
} else {
if(key.equalsIgnoreCase(currentKey)) {
// Do not remove the current entry
deleteEntries = true;
}
}
}
}
但后来我收到了 java.util.ConcurrentModificationException
。
我的第二个想法是先确定密钥,然后再删除它们。
public void removeEntriesAfter(String key) {
boolean deleteEntries = false;
List<String> listOfEntriesToBeRemoved = new ArrayList<String>();
// Determine entries to be deleted
for (String currentKey : var.keySet()) {
if(deleteEntries) {
listOfEntriesToBeRemoved.add(currentKey);
} else {
if(key.equalsIgnoreCase(currentKey)) {
// Do not remove the current entry
deleteEntries = true;
}
}
}
// Removed selected entries
for (String currentKey : listOfEntriesToBeRemoved) {
var.remove(currentKey);
}
}
这行得通,但我相信还有更多 elegant/efficient 方法可以做到这一点。
要避免 ConcurrentModificationException
,您可以使用 Iterator
。
Iterator<String> it = map.keySet().iterator();
while (it.hasNext())
if (it.next().equalsIgnoreCase(currentKey))
break;
while (it.hasNext()) {
it.next();
it.remove();
}
如果您想要最 有效的解决方案,首先是直接进入适当的条目。为此,您只需将小写键放入映射中(而不是放入任何旧字符串并使用 equalsIgnoreCase
进行比较)。然后,使用反射,您可以访问对应于 currentKey.toLowerCase()
的 Map.Entry
对象,然后再次使用反射,您可以在地图中一直跟踪链接。 None 无需反射即可实现,因为与键对应的条目和条目之间的链接都不会通过 public API 公开。我不建议反射,因为如果更改 LinkedHashMap
的代码,您的代码将来很容易中断。