Эффективный способ обрезки HashMap - PullRequest
1 голос
/ 06 декабря 2010

Я создаю Flyweight на Java и хочу убедиться, что я не создаю слишком большую карту.Есть ли более эффективный способ обрезать карту?Я не видел никаких свойств, которые могли бы делать это автоматически (например, конструктор максимального размера), поэтому я делаю это в коде.

Вот что у меня есть, оно довольно простое, но я хочу убедитьсяне лучший способ:

private static void prune() {
    Iterator<Entry<Integer, Integer[]>> iterator =  seeds.entrySet().iterator();
    int removed = 0;
    while(iterator.hasNext()|| removed == pruneLength) {
        iterator.next();
        iterator.remove();
        removed++;
    }
}

Ответы [ 4 ]

5 голосов
/ 06 декабря 2010

LinkedHashMap может использоваться как LRU-кеш.

Map<Integer, Integer[]> map = createLRUMap(128);

public static <K, V> Map<K, V> createLRUMap(final int maxSize) {
    return new LinkedHashMap<K,V>(maxSize, 1, true) {
        @Override
        protected boolean removeEldestEntry(Map.Entry<K,V> eldest) {
            return size() > maxSize;
        }
    };
}
3 голосов
/ 06 декабря 2010

Guava MapMaker имеет это в своей последней версии (на транке).Это должно быть в r08, хотя я не знаю, когда именно он выйдет.

ConcurrentMap<Integer, Integer[]> seeds = new MapMaker()
     .maximumSize(maxSize)
     .makeMap();

Обратите внимание, что это потокобезопасная параллельная карта, которая кажется важной в зависимости от того, как выиспользую его.

1 голос
/ 06 декабря 2010

Рассматривали ли вы использование кэшей, например, EhCache ? Они реализуют карты и декларативно вы можете установить размер, предел после того, как значения сохранены на диске и т. Д.

0 голосов
/ 06 декабря 2010

Одна возможность из мира баз данных - иметь две (или, возможно, несколько карт).Поиски используют обе карты.Пишет только одному.Когда записываемое устройство достигнет емкости, замените / очистите карту только для чтения и переключитесь.

...