![JAR search and dependency download from the Maven repository](/logo.png)
net.hasor.cobble.ref.WeakArrayList Maven / Gradle / Ivy
/*
* Copyright 2008-2009 the original author or authors.
*
* 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 net.hasor.cobble.ref;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.AbstractList;
import java.util.Arrays;
import java.util.Collection;
/**
* 弱引用列表,WeakArrayList是修改自 org.arakhne.util.ref 下的 WeakArrayList
* @version : 2013-11-8
* @author (网络收集)
*/
public class WeakArrayList extends AbstractList {
private static final Object NULL_VALUE = new Object();
private final transient ReferenceQueue queue;
private Object[] data;
private int size;
private boolean enquedElement;
private static T maskNull(final T value) {
return (T) (value == null ? WeakArrayList.NULL_VALUE : value);
}
private static T unmaskNull(final T value) {
return value == WeakArrayList.NULL_VALUE ? null : value;
}
public WeakArrayList(final int initialCapacity) {
this.queue = new ReferenceQueue();
this.enquedElement = false;
if (initialCapacity < 0) {
throw new IllegalArgumentException("Illegal Capacity: " + initialCapacity);
}
this.data = new Object[initialCapacity];
this.size = 0;
}
public WeakArrayList() {
this(10);
}
public WeakArrayList(final Collection extends T> c) {
this.queue = new ReferenceQueue();
this.enquedElement = false;
this.data = new Object[c.size()];
this.size = this.data.length;
int i = 0;
for (T t : c) {
this.data[i] = this.createRef(t);
++i;
}
}
@Override
public String toString() {
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < this.size; ++i) {
Object obj;
Reference> ref = (Reference>) this.data[i];
if (this.data[i] == null) {
obj = null;
} else {
obj = ref.get();
}
buffer.append('{');
buffer.append(obj == null ? null : obj.toString());
buffer.append('}');
}
return buffer.toString();
}
private Reference createRef(final T obj) {
return new WeakReference(WeakArrayList.maskNull(obj), this.queue);
}
public void ensureCapacity(final int minCapacity) {
this.modCount += 1;
int oldCapacity = this.data.length;
if (minCapacity > oldCapacity) {
Object[] oldData = this.data;
int newCapacity = oldCapacity * 3 / 2 + 1;
if (newCapacity < minCapacity) {
newCapacity = minCapacity;
}
this.data = Arrays.copyOf(oldData, newCapacity);
}
}
public void trimToSize() {
this.modCount += 1;
int oldCapacity = this.data.length;
if (this.size < oldCapacity) {
this.data = Arrays.copyOf(this.data, this.size);
}
}
@SuppressWarnings("unchecked")
public int expurge() {
int j;
while (this.queue.poll() != null) {
this.enquedElement = true;
}
if (this.enquedElement) {
j = 0;
for (int i = 0; i < this.size; ++i) {
Reference ref = (Reference) this.data[i];
if (ref == null || ref.isEnqueued() || ref.get() == null) {
if (ref != null) {
ref.clear();
}
this.data[i] = null;
} else {
if (i != j) {
this.data[j] = this.data[i];
this.data[i] = null;
}
++j;
}
}
this.enquedElement = false;
} else {
j = this.size;
}
while (this.queue.poll() != null) {
this.enquedElement = true;
}
this.size = j;
return this.size;
}
protected void assertRange(final int index, final boolean allowLast) {
int csize = this.expurge();
if (index < 0) {
throw new IndexOutOfBoundsException("invalid negative value: " + Integer.toString(index));
}
if (allowLast && index > csize) {
throw new IndexOutOfBoundsException("index>" + csize + ": " + Integer.toString(index));
}
if (!allowLast && index >= csize) {
throw new IndexOutOfBoundsException("index>=" + csize + ": " + Integer.toString(index));
}
}
@Override
public int size() {
return this.expurge();
}
@Override
@SuppressWarnings("unchecked")
public T get(final int index) {
Object value;
do {
this.assertRange(index, false);
value = ((Reference) this.data[index]).get();
} while (value == null);
return (T) WeakArrayList.unmaskNull(value);
}
@Override
@SuppressWarnings("unchecked")
public T set(final int index, final T element) {
Object oldValue;
Reference ref;
do {
this.assertRange(index, false);
ref = (Reference) this.data[index];
oldValue = ref.get();
} while (oldValue == null);
ref.clear();
this.data[index] = this.createRef(element);
this.modCount += 1;
return (T) WeakArrayList.unmaskNull(oldValue);
}
@Override
public void add(final int index, final T element) {
this.assertRange(index, true);
this.ensureCapacity(this.size + 1);
System.arraycopy(this.data, index, this.data, index + 1, this.size - index);
this.data[index] = this.createRef(element);
this.size += 1;
this.modCount += 1;
}
@Override
@SuppressWarnings("unchecked")
public T remove(final int index) {
Object oldValue;
Reference ref;
do {
this.assertRange(index, false);
ref = (Reference) this.data[index];
oldValue = ref.get();
} while (oldValue == null);
ref.clear();
System.arraycopy(this.data, index + 1, this.data, index, this.size - index - 1);
this.data[this.size - 1] = null;
this.size -= 1;
this.modCount += 1;
return (T) WeakArrayList.unmaskNull(oldValue);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy