如何有效地从Java中的LinkedHashMap中删除条目?

时间:2016-04-05 15:32:07

标签: java loops iterator iteration 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);
  }
}

这有效,但我确信有一种更优雅/更有效的方法。

1 个答案:

答案 0 :(得分:3)

要避免使用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进行比较)。然后,使用反射,您可以访问与Map.Entry对应的currentKey.toLowerCase()对象,然后再次使用反射,您可以一直跟踪地图中的链接。如果没有反射,这一切都不可能,因为对应于密钥的条目和条目之间的链接都不是通过公共API公开的。我不建议使用反射,因为如果更改了LinkedHashMap的代码,您的代码将来很容易破坏。