diff options
author | Wesley Wolfe <weswolf@aol.com> | 2013-04-02 07:52:17 -0500 |
---|---|---|
committer | Wesley Wolfe <weswolf@aol.com> | 2013-04-04 01:05:47 -0500 |
commit | 5634d9f701acea733fbe8c0f47c60369acfd56cd (patch) | |
tree | 6ebe10dba4b6ebd12ffa5583a82be4e5dfd12ba5 | |
parent | 3f637d17248df4fdec084d238b7eb4a1f6f15c1c (diff) | |
download | craftbukkit-5634d9f701acea733fbe8c0f47c60369acfd56cd.tar craftbukkit-5634d9f701acea733fbe8c0f47c60369acfd56cd.tar.gz craftbukkit-5634d9f701acea733fbe8c0f47c60369acfd56cd.tar.lz craftbukkit-5634d9f701acea733fbe8c0f47c60369acfd56cd.tar.xz craftbukkit-5634d9f701acea733fbe8c0f47c60369acfd56cd.zip |
Add a WeakCollection utility class.
This class is designed to be an invisible layer between a normal collection,
and one that silently loses entries because they are only weakly referencable.
Some operations have additional overhead to be semantically correct, but it
maintains the equals contract for all entries, as opposed to identity.
It does not support the equals or hash code method as it cannot easily have
the transitive and commutative properties.
-rw-r--r-- | src/main/java/org/bukkit/craftbukkit/util/WeakCollection.java | 173 |
1 files changed, 173 insertions, 0 deletions
diff --git a/src/main/java/org/bukkit/craftbukkit/util/WeakCollection.java b/src/main/java/org/bukkit/craftbukkit/util/WeakCollection.java new file mode 100644 index 00000000..d63348af --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/util/WeakCollection.java @@ -0,0 +1,173 @@ +package org.bukkit.craftbukkit.util; + +import java.lang.ref.WeakReference; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.NoSuchElementException; + +import org.apache.commons.lang.Validate; + + +public final class WeakCollection<T> implements Collection<T> { + static final Object NO_VALUE = new Object(); + private final Collection<WeakReference<T>> collection; + + public WeakCollection() { + collection = new ArrayList<WeakReference<T>>(); + } + + public boolean add(T value) { + Validate.notNull(value, "Cannot add null value"); + return collection.add(new WeakReference<T>(value)); + } + + public boolean addAll(Collection<? extends T> collection) { + Collection<WeakReference<T>> values = this.collection; + boolean ret = false; + for (T value : collection) { + Validate.notNull(value, "Cannot add null value"); + ret |= values.add(new WeakReference<T>(value)); + } + return ret; + } + + public void clear() { + collection.clear(); + } + + public boolean contains(Object object) { + if (object == null) { + return false; + } + for (T compare : this) { + if (object.equals(compare)) { + return true; + } + } + return false; + } + + public boolean containsAll(Collection<?> collection) { + return toCollection().containsAll(collection); + } + + public boolean isEmpty() { + return !iterator().hasNext(); + } + + public Iterator<T> iterator() { + return new Iterator<T>() { + Iterator<WeakReference<T>> it = collection.iterator(); + Object value = NO_VALUE; + + @Override + public boolean hasNext() { + Object value = this.value; + if (value != null && value != NO_VALUE) { + return true; + } + + Iterator<WeakReference<T>> it = this.it; + value = null; + + while (it.hasNext()) { + WeakReference<T> ref = it.next(); + value = ref.get(); + if (value == null) { + it.remove(); + } else { + this.value = value; + return true; + } + } + return false; + } + + @Override + public T next() throws NoSuchElementException { + if (!hasNext()) { + throw new NoSuchElementException("No more elements"); + } + + @SuppressWarnings("unchecked") + T value = (T) this.value; + this.value = NO_VALUE; + return value; + } + + @Override + public void remove() throws IllegalStateException { + if (value != NO_VALUE) { + throw new IllegalStateException("No last element"); + } + + value = null; + it.remove(); + } + }; + } + + public boolean remove(Object object) { + if (object == null) { + return false; + } + + Iterator<T> it = this.iterator(); + while (it.hasNext()) { + if (object.equals(it.next())) { + it.remove(); + return true; + } + } + return false; + } + + public boolean removeAll(Collection<?> collection) { + Iterator<T> it = this.iterator(); + boolean ret = false; + while (it.hasNext()) { + if (collection.contains(it.next())) { + ret = true; + it.remove(); + } + } + return ret; + } + + public boolean retainAll(Collection<?> collection) { + Iterator<T> it = this.iterator(); + boolean ret = false; + while (it.hasNext()) { + if (!collection.contains(it.next())) { + ret = true; + it.remove(); + } + } + return ret; + } + + public int size() { + int s = 0; + for (T value : this) { + s++; + } + return s; + } + + public Object[] toArray() { + return this.toArray(new Object[0]); + } + + public <T> T[] toArray(T[] array) { + return toCollection().toArray(array); + } + + private Collection<T> toCollection() { + ArrayList<T> collection = new ArrayList<T>(); + for (T value : this) { + collection.add(value); + } + return collection; + } +} |