Newer
Older
ultramine_bukkit / src / main / java / org / bukkit / craftbukkit / util / WeakCollection.java
@vlad20012 vlad20012 on 24 Feb 2017 3 KB initial
package org.bukkit.craftbukkit.util;

import org.apache.commons.lang.Validate;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.NoSuchElementException;

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;

			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;
			}

			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;
			}

			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;
	}
}