Edw*_*ard 3 java iteration iterator loops 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;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
但后来我收到了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);
}
}
Run Code Online (Sandbox Code Playgroud)
那行得通,但是我敢肯定有一种更优雅/更有效的方法。
要避免出现,ConcurrentModificationException您可以使用Iterator。
Iterator<String> it = map.keySet().iterator();
while (it.hasNext())
if (it.next().equalsIgnoreCase(currentKey))
break;
while (it.hasNext()) {
it.next();
it.remove();
}
Run Code Online (Sandbox Code Playgroud)
如果您想要最有效的解决方案,那将是直接直接进入相应的条目。为此,您只需将小写字母键放入映射中(而不是放入任何旧字符串并使用进行比较equalsIgnoreCase)。然后,使用反射,您可以访问Map.Entry与之相对应的对象currentKey.toLowerCase(),然后再次使用反射,您可以一直跟踪整个地图中的链接。没有反射就不可能做到这一点,因为与键对应的条目或条目之间的链接都不会通过公共API公开。我不建议您使用反射,因为如果LinkedHashMap更改了代码,将来您的代码很容易中断。