Какая польза от LinkedHashMap.removeEldestEntry?

Я знаю, что ответ на этот вопрос легко доступен в Интернете. Мне нужно знать, что произойдет, если я выберу не removeEldestEntry. Ниже мой код:

package collection;

import java.util.*;

public class MyLinkedHashMap {

   private static final int MAX_ENTRIES = 2;

   public static void main(String[] args) {
      LinkedHashMap lhm = new LinkedHashMap(MAX_ENTRIES, 0.75F, false) {

         protected boolean removeEldestEntry(Map.Entry eldest) {
            return false;
         }
      };
      lhm.put(0, "H");
      lhm.put(1, "E");
      lhm.put(2, "L");
      lhm.put(3, "L");
      lhm.put(4, "O");

      System.out.println("" + lhm);

   }
}

Даже если я не разрешаю removeEldestEntry мой код работает нормально. Итак, внутренне, что происходит?

Ответы

Ответ 1

removeEldestEntry всегда проверяется после того, как элемент был вставлен. Например, если вы переопределите метод, чтобы всегда возвращать значение true, LinkedHashMap всегда будет пустым, поскольку после каждой вставки put или putAll старший элемент будет удален, несмотря ни на что. JavaDoc показывает очень разумный пример того, как его использовать:

protected boolean removeEldestEntry(Map.Entry eldest){
    return size() > MAX_SIZE;
}

Альтернативным способом может потребоваться удалить запись, если она не важна:

protected boolean removeEldestEntry(Map.Entry eldest){
    if(size() > MAX_ENTRIES){
       if(isImportant(eldest)){
          //Handle an important entry here, like reinserting it to the back of the list
          this.remove(eldest.getKey());
          this.put(eldest.getKey(), eldest.getValue());
          //removeEldestEntry will be called again, now with the next entry
          //so the size should not exceed the MAX_ENTRIES value
          //WARNING: If every element is important, this will loop indefinetly!
       } else {
           return true; //Element is unimportant
       }
    return false; //Size not reached or eldest element was already handled otherwise
}

Ответ 2

Почему люди просто не могут ответить на простой вопрос OP?

Если removeEldestEntry возвращает false, то никакие элементы никогда не будут удалены с карты, и это будет по существу вести себя как обычный Map.

Ответ 3

Ваш метод removeEldestEntry идентичен стандартным реализациям LinkedHashMap.removeEldestEntry, поэтому ваш LinkedHashMap будет просто вести себя как обычный LinkedHashMap без переопределенных методов, сохраняя все значения и ключи, введенные в него, пока и пока вы явно не удалите их путем вызова remove, removeAll, clear и т.д. Преимущество использования LinkedHashMap заключается в том, что представления коллекции (keySet(), values(), entrySet()) всегда возвращают итераторы, которые пересекают ключи и/или значения в том порядке, в котором они были добавлены к карте.

Ответ 4

Расширение ответа на @DavidNewcomb:

Я предполагаю, что вы изучаете, как реализовать кеш.

Метод LinkedHashMap.removeEldestEntry - это метод, который очень часто используется в структурах данных кэша, где размер кеша ограничен определенным порогом. В таких случаях метод removeEldestEntry может быть установлен для автоматического удаления самой старой записи, когда размер превышает пороговое значение (определяется атрибутом MAX_ENTRIES) - как в приведенном примере здесь.

С другой стороны, когда вы переопределяете метод removeEldestEntry таким образом, вы гарантируете, что ничего не произойдет, когда превышен порог MAX_ENTRIES. Другими словами, структура данных не будет вести себя как кэш, а скорее нормальная карта.