java - 是否有针对 Java 的弱引用写时复制集的开源实现?

标签 java collections weak-references

接近 http://code.google.com/p/red5/source/browse/java/server/trunk/src/org/red5/server/ClientList.java?r=3747 的东西, 但由 CopyOnWriteArraySet 而不是 CopyOnWriteArrayList 支持。

最佳答案

这是我尝试创建一个弱引用的写时复制数组集。 我根据你在问题中提供的列表实现重写了它。 iterator 方法是唯一的主要添加和 add 中的一个小更改使行为与集合兼容的方法。然后我删除了一些集合实现不需要的方法。

注意:我对该代码进行了基本测试并且它通过了。但这可能不是最有效的实现,也没有经过全面测试。需要您自担风险使用它。

更新:添加了对remove() 方法的removeReleased() 调用,这样iterator() 就不会迭代时返回删除的元素。


public class CopyOnWriteWeakReferenceSet<E> extends AbstractSet<E> {

    private static final long serialVersionUID = -3127064371410565215L;

    private CopyOnWriteArraySet<WeakReference<E>> items;

    public CopyOnWriteWeakReferenceSet() {
        items = new CopyOnWriteArraySet<WeakReference<E>>();
    }

    public CopyOnWriteWeakReferenceSet(Collection<E> c) {
        items = new CopyOnWriteArraySet<WeakReference<E>>();
        addAll(c);
    }

    public boolean add(E element) {
        if (contains(element)) return false;
        return items.add(new WeakReference<E>(element));
    }

    @Override
    public boolean remove(Object o) {
        boolean removed = false;
        E element = null;
        for (WeakReference<E> ref : items) {
            element = ref.get();
            if (element != null && element.equals(o)) {
                ref.clear();
                removed = true;
                break;
            }
        }
        if (removed) removeReleased();
        return removed;
    }

    @Override
    public boolean contains(Object o) {
        List<E> list = new ArrayList<E>();
        for (WeakReference<E> ref : items) {
            if (ref.get() != null) {
                list.add(ref.get());
            }
        }
        boolean contains = list.contains(o);
        list.clear();
        list = null;
        return contains;
    }

    public int size() {
        removeReleased();
        return items.size();
    }

    private void removeReleased() {
        for (WeakReference<E> ref : items) {
            if (ref.get() == null) {
                items.remove(ref);
            }
        }
    }

    @Override
    public Iterator<E> iterator() {
        final Iterator<WeakReference<E>> iter = items.iterator();
        return new Iterator<E>() {

            @Override
            public boolean hasNext() {
                return iter.hasNext();
            }

            @Override
            public E next() {
                return iter.next().get();
            }

            @Override
            public void remove() {
                iter.remove();
            }
        };
    }

    public static void main(String[] args) {
        CopyOnWriteWeakReferenceSet<String> set = new 
                              CopyOnWriteWeakReferenceSet<String>();
        set.add("3");
        set.add("1");
        set.add("2");
        set.add("1");

        //testing iterator multiple times
        System.out.println("----------------------------");
        System.out.println("Iterator test start");
        System.out.println("----------------------------");
        for (String str : set) {
            System.out.println(str);
        }
        System.out.println("----------------------------");
        for (String str : set) {
            System.out.println(str);
        }
        System.out.println("----------------------------");
        for (String str : set) {
            System.out.println(str);
        }
        System.out.println("----------------------------");
        //Trying iteration using iterator object 
        Iterator<String> strIter = set.iterator();
        while(strIter.hasNext()) {
            System.out.println(strIter.next());
            //This remove call will throw 
            //java.lang.UnsupportedOperationException 
            //even on the original CopyOnWriteArraySet.
            //strIter.remove();
        }
        System.out.println("----------------------------");
        System.out.println("Iterator test end");

        System.out.println("----------------------------");

        System.out.println("----------------------------");
        System.out.println("Remove test start");
        System.out.println("----------------------------");
        System.out.println("Set size now " + set.size());
        set.remove("3");
        System.out.println(set.contains("3")); //false
        for (String str : set) {
            System.out.println(str); //1 and 2
        }
        System.out.println("Set size now " + set.size()); //2
        System.out.println("----------------------------");
        System.out.println("Remove test end");
        System.out.println("----------------------------");
    }
}

关于java - 是否有针对 Java 的弱引用写时复制集的开源实现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7900115/

相关文章:

java - TextView 在水平布局中不可见

java - 对 ArrayList 使用可选索引 - 可能吗?

c++ - weak_ptr 是如何工作的?

java - 在 IntelliJ IDEA 中创建数据库

java - 当PK删除不存在的数据时,如何处理Spring Data JPA删除?

java.lang.NumberFormatException : Invalid double: "١2" Problem with numbers processing in Persian

java - 在 Java 8 中将 lambda 表达式与旧集合类一起使用时,避免使用 .stream() 和 .collect()

java - 我可以包装多个 Java 排序集,使它们看起来像一个吗?

objective-c - 使用 __block 和 __weak

swift - 单元测试时 waitForExpectations 上的 EXC_BAD_ACCESS