1年前 (2022-12-19)  Java系列 |   抢沙发  291 
文章评分 0 次,平均分 0.0

大家都知道Java里有WeakHashMap这样的数据结构,一个弱引用的Map,在内存不足GC时Entry会被回收掉,可以避免内存泄露的风险,虽然Java原生的Collections中并没有提供WeakSetWeakList这样的数据结构,但自己实现也不难,其中最简单的方式是使用Collections.newSetFromMap转换一下:

Set<Object> weakHashSet = 
    Collections.newSetFromMap(
        new WeakHashMap<Object, Boolean>()
    );

这种方式虽然简单但用例实际上非常有限,下面是一个使用WeakReference实现的WeakList类:

public class WeakList extends AbstractList {
    
    private ArrayList items;

    public WeakList() {
        items = new ArrayList();
    }
    
    public WeakList(Collection c) {
        items = new ArrayList();
        addAll(0, c);
    }
    
    public void add(int index, Object element) {
        items.add(index, new WeakReference(element));
    }
    
    public Iterator iterator() {
        return new WeakListIterator();
    }
    
    public int size() {
        removeReleased();
        return items.size();
    }    
    
    public java.lang.Object get(int index) {
        return ((WeakReference) items.get(index)).get();
    }
    
    private void removeReleased() {
        for (Iterator it = items.iterator(); it.hasNext(); ) {
            WeakReference ref = (WeakReference) it.next();
            if (ref.get() == null) items.remove(ref);
        }
    }
    
    private class WeakListIterator implements Iterator {
        
        private int n;
        private int i;
        
        public WeakListIterator() {
            n = size();
            i = 0;
        }
        
        public boolean hasNext() {
            return i < n;
        }
        
        public Object next() {
            return get(i++);
        }
        
        public void remove() {
            throw new UnsupportedOperationException();
        }
        
    }

}

另外有两个开源的github库也实现了类似的结构,可以参考下:

https://github.com/geotools/geotools/blob/main/modules/library/metadata/src/main/java/org/geotools/util/WeakHashSet.java

https://github.com/JetBrains/intellij-community/blob/master/platform/util/src/com/intellij/util/containers/WeakList.java

 

除特别注明外,本站所有文章均为老K的Java博客原创,转载请注明出处来自https://javakk.com/2770.html

关于

发表评论

表情 格式

暂无评论

登录

忘记密码 ?

切换登录

注册