2011-10-26 12 views
2

何かがhttp://code.google.com/p/red5/source/browse/java/server/trunk/src/org/red5/server/ClientList.java?r=3747に近いものの、CopyOnWriteArrayListの代わりにCopyOnWriteArraySetが付いています。私はこれを見つけるためにweakreference copyonwritearraysetをググJava用の弱参照コピーオンライトセットのオープンソース実装はありますか?

http://docs.jboss.org/modeshape/0.5/apidocs/src-html/org/jboss/dna/graph/observe/ChangeObserver.html

注:それに近い

答えて

1

弱参照コピーオンライトアレイセットを作成しようとしました。 質問に記載されているリストの実装に基づいて書き換えました。iteratorメソッドは、ビヘイビアをセットと互換性を持たせるための唯一のメジャーな追加とマイナーな変更です。次に、実装された実装では不要なメソッドをいくつか削除しました。

注::このコードの基本テストを行いました。しかし、これは最も効率的な実装でも、完全にテストされたものでもないかもしれません。自己責任で使用してください。

更新:反復しながら、iterator()が取り除かれた要素を返さないようにremove()メソッドへremoveReleased()の呼び出しを追加しました。


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("----------------------------"); 
    } 
} 
+0

セットの 'contains'メソッドは、本当にセット全体を反復すべきではありません。 –

+1

@AlexeyRomanov私は弱い参照セットがその要素がその中に存在するかどうかを見つけるためにセット全体を反復することを避けることが可能かどうかはわかりません。通常の(弱い参照でなくても) 'CopyOnWriteArraySet'は' CopyOnWriteArrayList'によってサポートされ、 'contains'を実装するためにセット全体を反復処理します。 –

関連する問題