缺少对值的弱引用的hashmap?

Raz*_*orm 9 java android weak-references

我正在构建一个Android应用程序,其中每个实体都有一个代表其精灵的位图.但是,每个实体都可以复制(例如,可能有3个实体asdf副本).

一种方法是预先加载所有sprite,然后将正确的sprite放在实体的构造函数中.

但是,我想懒惰地解码位图,以便实体的构造函数将解码位图.唯一的问题是重复的实体将使用2倍的内存加载相同的位图两次(如果实体创建n次,则加载n次).

为了解决这个问题,我构建了一个SingularBitmapFactory,它将一个已解码的Bitmap存储到一个哈希中,如果再次询问相同的位图,则只返回先前的哈希值而不是构建一个新的哈希值.但问题是,工厂持有所有位图的副本,因此不会收集垃圾.

将hashmap切换为弱引用值的最佳方法是什么?换句话说,我想要一个结构,如果任何其他对象持有对它的引用,那么值将不会是GC,但只要没有其他对象引用它,那么它可以是GC'd.

iag*_*een 12

你所说的几乎 - 使Bitmap(地图的物体侧)成为WeakReference而不是Bitmap.然后,您必须添加额外的检查以查看引用在将其传递回实体之前是否仍然有效.这是一般概念的快速草图.

public class SingularBitmapFactory { 
    private HashMap <String, WeakReference<Bitmap>> cache = new HashMap<String, WeakReference<Bitmap>>();

    public Bitmap getBitmap(String key) {
        Bitmap image = null;
        WeakReference<Bitmap> ref = cache.get(key);
        if(ref != null) {
            image = ref.get();
        }
        if(image == null) {
            // Load image here ... 
            cache.put(key, new WeakReference<Bitmap>(image));
        }
        return image;   
    }
}
Run Code Online (Sandbox Code Playgroud)


rup*_*pps 7

老问题,但今天我需要这个,基于@ iagreen的答案我已经概括了这个想法,也许它对某人来说很方便...

public static class WeakValueHashMap<K,V> {
    private HashMap<K,WeakReference<V>> mDatabase=new HashMap<K, WeakReference<V>>();
    public V get(K key) {
        WeakReference<V> weakRef=mDatabase.get(key);
        if (weakRef==null) return null;
        V result=weakRef.get();
        if (result==null) {
            // edge case where the key exists but the object has been garbage collected
            // we remove the key from the table, because tables are slower the more
            // keys they have (@kisp's comment)
            mDatabase.remove(key);
        }
        return result;
    }
    public void put(K key, V value) {
        mDatabase.put(key, new WeakReference<V>(value));
    }
}
Run Code Online (Sandbox Code Playgroud)

所以你可以这样做

    private WeakValueHashMap<String,Drawable> mTextDrawables=new WeakValueHashMap<String,Drawable>();
Run Code Online (Sandbox Code Playgroud)

并且Drawables将与之一起存储Weakreferences.

方法"containsValue"实现起来比较棘手,你必须迭代并取消引用所有的WeakRefs ......

  • 它看起来很不错:我认为你应该照顾过时的密钥删除.一段时间后,很多键会使查找速度变慢.(loadFactor会很高,会消耗很多空间).如果你也没有删除密钥.建议:如果weakRef == null,请在get方法中删除mDatabase.干杯 (3认同)