2009-05-14 2 views
4

Есть ли на LinkedHashMap основе на основе ссылок на Java? Если нет, есть ли у кого-нибудь фрагмент кода, который я могу, вероятно, повторно использовать? Я обещаю правильно его исправить.Софт Ссылка LinkedHashMap в Java?

Спасибо.

+4

Если вы планируете делать это для кэша, чувствительного к памяти, имейте в виду, что доступная память - очень плохой способ регулировать что-либо. В среде с большими кучами вы можете хранить устаревшие объекты в течение очень долгого времени, что замедляет общую работу. Временные и размерные кэши намного лучше. Вы также можете быть заинтересованы в следующем: http://www.kdgregory.com/index.php?page=java.refobj – kdgregory

ответ

3

Лучшая идея, которую я видел для этого, - это обернуть LinkedHashMap, чтобы все, что вы put, было WeakReference.

ОБНОВЛЕНИЕ: Просто просмотрел источник WeakHashMap и способ, которым он обрабатывает все, что WeakReference, все еще играя хорошо с дженериками, прочен. Вот основной класс подпись он использует:

private static class Entry<K,V> extends WeakReference<Object> implements Map.Entry<K,V> 

Я предлагаю просмотр более the source в глубине для других идей реализации.

ОБНОВЛЕНИЕ 2: kdgregory поднимает хороший момент в своем комментарии - все мое предложение делает это, чтобы ссылки в Map не заставили референта быть собраны в мусор. Вам все равно нужно очистить мертвые ссылки вручную.

+3

Это не совсем работает, потому что ссылки никогда не исчезнут, они просто очистятся. И вы получите карту, полную мертвых ссылок. Если вы посмотрите на код WeakHashMap, вы увидите, что он лениво очищает мертвые ссылки (я считаю, используя ссылочную очередь). – kdgregory

6

WeakHashMap не сохраняет порядок вставки. Таким образом, это не может рассматриваться как прямая замена LinkedHashMap. Кроме того, запись на карте выдается только тогда, когда ключ больше недоступен. Возможно, это не то, что вы ищете.

Если вы ищете удобный для хранения данных кеш, вот наивная реализация, которую вы могли бы использовать.

package be.citobi.oneshot; 

import java.lang.ref.SoftReference; 
import java.util.LinkedHashMap; 

public class SoftLinkedCache<K, V> 
{ 
    private static final long serialVersionUID = -4585400640420886743L; 

    private final LinkedHashMap<K, SoftReference<V>> map; 

    public SoftLinkedCache(final int cacheSize) 
    { 
     if (cacheSize < 1) 
      throw new IllegalArgumentException("cache size must be greater than 0"); 

     map = new LinkedHashMap<K, SoftReference<V>>() 
     { 
      private static final long serialVersionUID = 5857390063785416719L; 

      @Override 
      protected boolean removeEldestEntry(java.util.Map.Entry<K, SoftReference<V>> eldest) 
      { 
       return size() > cacheSize; 
      } 
     }; 
    } 

    public synchronized V put(K key, V value) 
    { 
     SoftReference<V> previousValueReference = map.put(key, new SoftReference<V>(value)); 
     return previousValueReference != null ? previousValueReference.get() : null; 
    } 

    public synchronized V get(K key) 
    { 
     SoftReference<V> valueReference = map.get(key); 
     return valueReference != null ? valueReference.get() : null; 
    } 
} 
2

взгляните на this post. Он показывает, как реализовать SoftHashMap ...

+2

Apache Shiro уже имеет реализацию этого метода (с одобрением) и лицензировал его под Apache v2. Он упакован с Apache [Shiro] [1]. Вы можете найти документацию [здесь] [2] и исходный код [здесь] [3]. [1]: http://en.wikipedia.org/wiki/Apache_Shiro [2]: http://shiro.apache.org/static/1.1.0/apidocs/ [3]: http: //shiro.apache.org/static/1.1.0/apidocs/src-html/org/apache/shiro/util/SoftHashMap.html – DallinDyer