简体   繁体   中英

How to efficiently remove entries from a LinkedHashMap in Java?

I want to remove all entries from a LinkedHashMap that were added after an entry with a given key.

My first try was:

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;
      }
    }
  }
}

But then I received a java.util.ConcurrentModificationException .

My second idea was to first determine the keys, an remove them afterwards.

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);
  }
}

That works, but I'm sure there is a more elegant/efficient way of doing this.

To avoid a ConcurrentModificationException you can use an Iterator .

Iterator<String> it = map.keySet().iterator();
while (it.hasNext())
    if (it.next().equalsIgnoreCase(currentKey))
        break;
while (it.hasNext()) {
    it.next();
    it.remove();
}

If you wanted the most efficient solution, it would be to go straight to the appropriate entry in the first place. To do this you would have to only ever put lower case keys into the map (rather than putting any old strings and comparing using equalsIgnoreCase ). Then, using reflection, you could access the Map.Entry object corresponding to currentKey.toLowerCase() and then, using reflection again, you could follow the links all the way through the map. None of this is possible without reflection because neither the entry corresponding to a key nor the links between entries are exposed through public API. I do not recommend reflection as your code could easily break in the future if the code for LinkedHashMap is changed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM