/*
* Copyright 2013 Serdar.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.fub.utilsmodule.Collections;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
/**
*
* @author Serdar
* @param <T>
*/
public class WeakList<T> implements List<T> {
private final ArrayList<WeakReference<T>> weakReferences = new ArrayList<WeakReference<T>>();
private WeakReference<T> createWeakReference(T ref) {
return new WeakReference<T>(ref);
}
private void checkListAndRemove() {
synchronized (weakReferences) {
ArrayList<WeakReference<T>> arrayL = new ArrayList<WeakReference<T>>(weakReferences);
for (WeakReference<T> ref : arrayL) {
if (ref.get() == null) {
weakReferences.remove(ref);
}
}
arrayL.clear();
}
}
@Override
public int size() {
checkListAndRemove();
return weakReferences.size();
}
@Override
public boolean isEmpty() {
checkListAndRemove();
return weakReferences.isEmpty();
}
@Override
public boolean contains(Object o) {
synchronized (weakReferences) {
for (WeakReference<T> weakRef : weakReferences) {
if (weakRef.get() != null && weakRef.get().equals(o)) {
return true;
}
}
return false;
}
}
@Override
public Iterator<T> iterator() {
checkListAndRemove();
return new Iterator<T>() {
int i = 0;
@Override
public boolean hasNext() {
return weakReferences.size() > i;
}
@Override
public T next() {
return weakReferences.get(i++).get();
}
@Override
public void remove() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
};
}
@Override
public Object[] toArray() {
synchronized (weakReferences) {
Object[] array = new Object[size()];
for (int i = 0; i < array.length; i++) {
WeakReference<T> ref = weakReferences.get(i);
if (ref.get() != null) {
array[i] = ref.get();
}
}
return array;
}
}
@Override
@SuppressWarnings("unchecked")
public <T> T[] toArray(T[] a) {
synchronized (weakReferences) {
ArrayList<T> elemArray = new ArrayList<T>();
for (WeakReference<?> ref : weakReferences) {
if (ref.get() != null) {
elemArray.add((T) ref.get());
}
}
return elemArray.toArray(a);
}
}
@Override
public boolean add(T e) {
synchronized (weakReferences) {
return weakReferences.add(createWeakReference(e));
}
}
@Override
public boolean remove(Object o) {
synchronized (weakReferences) {
int indexOf = indexOf(o);
if (indexOf > -1) {
return remove(indexOf) != null;
} else {
return false;
}
}
}
@Override
public boolean containsAll(Collection<?> c) {
boolean result = true;
for (Object o : c) {
if (!contains(c)) {
result = false;
break;
}
}
return result;
}
@Override
public boolean addAll(Collection<? extends T> c) {
synchronized (weakReferences) {
boolean result = true;
for (T element : c) {
result &= add(element);
}
return result;
}
}
@Override
public boolean addAll(int index, Collection<? extends T> c) {
synchronized (weakReferences) {
boolean result = true;
for (T elem : c) {
add(index++, elem);
}
return result;
}
}
@Override
public boolean removeAll(Collection<?> c) {
synchronized (weakReferences) {
boolean result = true;
for (Object o : c) {
result &= remove(o);
}
return result;
}
}
@Override
public boolean retainAll(Collection<?> c) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void clear() {
weakReferences.clear();
}
@Override
public T get(int index) {
synchronized (weakReferences) {
WeakReference<T> ref = weakReferences.get(index);
if (ref.get() == null) {
weakReferences.remove(ref);
}
return ref.get();
}
}
@Override
public T set(int index, T element) {
assert element != null : "null elements are not supported!";
synchronized (weakReferences) {
return weakReferences.set(index, createWeakReference(element)).get();
}
}
@Override
public void add(int index, T element) {
assert element != null : "null elements are not supported!";
synchronized (weakReferences) {
weakReferences.add(index, createWeakReference(element));
}
}
@Override
public T remove(int index) {
synchronized (weakReferences) {
WeakReference<T> ref = weakReferences.remove(index);
return ref == null ? null : ref.get();
}
}
@Override
public int indexOf(Object o) {
synchronized (weakReferences) {
for (WeakReference<T> ref : weakReferences) {
if (ref.get() != null && ref.get().equals(o)) {
return weakReferences.indexOf(ref);
}
}
}
return -1;
}
@Override
public int lastIndexOf(Object o) {
synchronized (weakReferences) {
WeakReference<T> ref = null;
for (int i = weakReferences.size() - 1; i > -1; i--) {
ref = weakReferences.get(i);
if (ref != null && ref.get() != null && ref.get().equals(o)) {
return i;
}
}
return -1;
}
}
@Override
public ListIterator<T> listIterator() {
synchronized (weakReferences) {
checkListAndRemove();
return new ListIterator<T>() {
private ListIterator<WeakReference<T>> it = weakReferences.listIterator();
@Override
public boolean hasNext() {
return it.hasNext();
}
@Override
public T next() {
return it.next().get();
}
@Override
public boolean hasPrevious() {
return it.hasPrevious();
}
@Override
public T previous() {
return it.previous().get();
}
@Override
public int nextIndex() {
return it.nextIndex();
}
@Override
public int previousIndex() {
return it.previousIndex();
}
@Override
public void remove() {
it.remove();
}
@Override
public void set(T e) {
it.set(createWeakReference(e));
}
@Override
public void add(T e) {
it.add(createWeakReference(e));
}
};
}
}
@Override
public ListIterator<T> listIterator(final int index) {
synchronized (weakReferences) {
checkListAndRemove();
return new ListIterator<T>() {
private ListIterator<WeakReference<T>> it = weakReferences.listIterator(index);
@Override
public boolean hasNext() {
return it.hasNext();
}
@Override
public T next() {
return it.next().get();
}
@Override
public boolean hasPrevious() {
return it.hasPrevious();
}
@Override
public T previous() {
return it.previous().get();
}
@Override
public int nextIndex() {
return it.nextIndex();
}
@Override
public int previousIndex() {
return it.previousIndex();
}
@Override
public void remove() {
it.remove();
}
@Override
public void set(T e) {
it.set(createWeakReference(e));
}
@Override
public void add(T e) {
it.add(createWeakReference(e));
}
};
}
}
@Override
public List<T> subList(int fromIndex, int toIndex) {
synchronized (weakReferences) {
List<WeakReference<T>> subList = weakReferences.subList(fromIndex, toIndex);
ArrayList<T> arrayList = new ArrayList<T>();
for (WeakReference<T> ref : weakReferences) {
if (ref.get() != null) {
arrayList.add(ref.get());
}
}
return arrayList;
}
}
}