sclass CircularArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, Serializable {
private transient Object[] elementData;
private int size;
private int head;
private int tail;
*(int initialCapacity) {
if (initialCapacity < 0) {
throw new IllegalArgumentException(
"Illegal Capacity: " + initialCapacity);
}
elementData = new Object[initialCapacity];
size = tail = head = 0;
}
*() { this(10); }
*(Collection<? extends E> c) {
elementData = c.toArray();
tail = 0;
size = head = elementData.length;
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
}
private void copy(Object[] src, Object[] dest) {
System.arraycopy(src, 0, dest, 0, head);
System.arraycopy(src, src.length + tail,
dest, dest.length + tail, -tail);
}
private void ensureCapacityInternal(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
/**
* Increases the capacity to ensure that it can hold at least the
* number of elements specified by the minimum capacity argument.
*
* @param minCapacity the desired minimum capacity
*/
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
Object[] oldData = elementData;
elementData = new Object[newCapacity];
copy(oldData, elementData);
}
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;
}
public int size() {
return size;
}
public boolean isEmpty() {
return size == 0;
}
public boolean contains(Object o) {
return indexOf(o) >= 0;
}
public int indexOf(Object o) {
if (o == null) {
for (int i = 0; i < size; i++)
if (elementData[pos(i)] == null)
return i;
} else {
for (int i = 0; i < size; i++)
if (o.equals(elementData[pos(i)]))
return i;
}
return -1;
}
public int lastIndexOf(Object o) {
if (o == null) {
for (int i = size - 1; i >= 0; i--)
if (elementData[pos(i)] == null)
return i;
} else {
for (int i = size - 1; i >= 0; i--)
if (o.equals(elementData[pos(i)]))
return i;
}
return -1;
}
public Object clone() {
try {
@SuppressWarnings("unchecked")
CircularArrayList<E> c = (CircularArrayList<E>) super.clone();
c.elementData = new Object[size];
copy(elementData, c.elementData);
c.modCount = 0;
return c;
} catch (CloneNotSupportedException e) {
// this shouldn't happen, since we are Cloneable
throw new InternalError();
}
}
public Object[] toArray() {
Object[] a = new Object[size];
System.arraycopy(elementData, elementData.length + tail, a, 0, -tail);
System.arraycopy(elementData, 0, a, -tail, head);
return a;
}
public <T> T[] toArray(T[] a) {
if (a.length < size) {
// Make a new array of a's runtime type
a = ((Object)a.getClass() == (Object)Object[].class)
? (T[]) new Object[size]
: (T[]) Array.newInstance(a.getClass().getComponentType(), size);
}
System.arraycopy(elementData, elementData.length + tail, a, 0, -tail);
System.arraycopy(elementData, 0, a, -tail, head);
if (a.length > size) {
a[size] = null;
}
return a;
}
private int pos(int index) {
return (elementData.length + tail + index) % elementData.length;
}
public E get(int index) {
rangeCheck(index);
return (E) elementData[pos(index)];
}
public E set(int index, E element) {
rangeCheck(index);
int pos = pos(index);
E oldValue = (E) elementData[pos];
elementData[pos] = element;
return oldValue;
}
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[head] = e;
head++;
size++;
return true;
}
public void add(int index, E element) {
rangeCheckForAdd(index);
ensureCapacityInternal(size + 1); // Increments modCount!!
int i = index + tail;
if (i <= 0) {
System.arraycopy(elementData, elementData.length + tail,
elementData, elementData.length + tail - 1,
index);
elementData[elementData.length + i - 1] = element;
tail--;
} else {
System.arraycopy(elementData, i, elementData, i + 1, size - index);
elementData[i] = element;
head++;
}
size++;
}
public E remove(int index) {
rangeCheck(index);
E value = (E) elementData[pos(index)];
fastRemove(index);
return value;
}
public boolean remove(Object o) {
if (o == null) {
for (int index = 0; index < size; index++)
if (elementData[pos(index)] == null) {
fastRemove(index);
return true;
}
} else {
for (int index = 0; index < size; index++)
if (o.equals(elementData[pos(index)])) {
fastRemove(index);
return true;
}
}
return false;
}
private void fastRemove(int index) {
modCount++;
int i = index + tail;
if (i < 0) {
int numMoved = index;
if (numMoved > 0)
System.arraycopy(elementData, elementData.length + tail,
elementData, elementData.length + tail + 1,
numMoved);
elementData[elementData.length + tail] = null; // Let gc do its work
tail++;
} else {
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, i + 1, elementData, i, numMoved);
head--;
elementData[head] = null; // Let gc do its work
}
size--;
}
public void clear() {
modCount++;
// Let gc do its work
for (int i = 0; i < size; i++)
elementData[pos(i)] = null;
size = tail = head = 0;
}
public boolean addAll(Collection<? extends E> c) {
Object[] a = c.toArray();
int numNew = a.length;
ensureCapacityInternal(size + numNew); // Increments modCount
System.arraycopy(a, 0, elementData, head, numNew);
head += numNew;
size += numNew;
return numNew != 0;
}
private void rangeCheck(int index) {
if (index >= size || index < 0) {
throw new IndexOutOfBoundsException(
"Index: " + index + ", Size: " + size);
}
}
private void rangeCheckForAdd(int index) {
if (index > size || index < 0)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
private String outOfBoundsMsg(int index) {
return "Index: " + index + ", Size: " + size;
}
}TODO: fast removal of sublist From https://github.com/andrioli/circular-array-list/blob/master/src/main/java/br/com/ooboo/util/CircularArrayList.java
download show line numbers debug dex old transpilations
Travelled to 14 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, irmadwmeruwu, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt
No comments. add comment
| Snippet ID: | #1013598 |
| Snippet name: | CircularArrayList - list with fast remove/add at both ends; not synchronized; broken? |
| Eternal ID of this version: | #1013598/6 |
| Text MD5: | ca6f9c7033542f5bca27965182478cb1 |
| Author: | stefan |
| Category: | javax / collections |
| Type: | JavaX fragment (include) |
| Public (visible to everyone): | Yes |
| Archived (hidden from active list): | No |
| Created/modified: | 2018-06-29 01:38:11 |
| Source code size: | 7312 bytes / 294 lines |
| Pitched / IR pitched: | No / No |
| Views / Downloads: | 908 / 1489 |
| Version history: | 5 change(s) |
| Referenced in: | [show references] |