204 lines
5.7 KiB
Java
204 lines
5.7 KiB
Java
|
|
package de.vivi.list;
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
import java.util.*;
|
||
|
|
|
||
|
|
public class ArrayByteList<E> extends AbstractList<E> implements ByteList<E> {
|
||
|
|
|
||
|
|
transient Object[] elementData;
|
||
|
|
public static final int SOFT_MAX_ARRAY_LENGTH = Integer.MAX_VALUE - 8;
|
||
|
|
private static final int DEFAULT_CAPACITY = 10;
|
||
|
|
private int size;
|
||
|
|
private static final Object[] EMPTY_ELEMENTDATA = {};
|
||
|
|
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
|
||
|
|
|
||
|
|
public ArrayByteList(int initialCapacity) {
|
||
|
|
if (initialCapacity > 0) {
|
||
|
|
this.elementData = new Object[initialCapacity];
|
||
|
|
} else if (initialCapacity == 0) {
|
||
|
|
this.elementData = EMPTY_ELEMENTDATA;
|
||
|
|
} else {
|
||
|
|
throw new IllegalArgumentException("Illegal Capacity: "+
|
||
|
|
initialCapacity);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public ArrayByteList() {
|
||
|
|
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
|
||
|
|
}
|
||
|
|
|
||
|
|
public ArrayByteList(Collection<? extends E> c) {
|
||
|
|
Object[] a = c.toArray();
|
||
|
|
if ((size = a.length) != 0) {
|
||
|
|
if (c.getClass() == ArrayList.class) {
|
||
|
|
elementData = a;
|
||
|
|
} else {
|
||
|
|
elementData = Arrays.copyOf(a, size, Object[].class);
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
// replace with empty array.
|
||
|
|
elementData = EMPTY_ELEMENTDATA;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
@Override
|
||
|
|
public boolean add(E e) {
|
||
|
|
modCount++;
|
||
|
|
add(e, elementData, size);
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
public void trimToSize() {
|
||
|
|
modCount++;
|
||
|
|
if (size < elementData.length) {
|
||
|
|
elementData = (size == 0)
|
||
|
|
? EMPTY_ELEMENTDATA
|
||
|
|
: Arrays.copyOf(elementData, size);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public void add(int index, E element) {
|
||
|
|
rangeCheckForAdd(index);
|
||
|
|
modCount++;
|
||
|
|
final int s;
|
||
|
|
Object[] elementData;
|
||
|
|
if ((s = size) == (elementData = this.elementData).length)
|
||
|
|
elementData = grow();
|
||
|
|
System.arraycopy(elementData, index,
|
||
|
|
elementData, index + 1,
|
||
|
|
s - index);
|
||
|
|
elementData[index] = element;
|
||
|
|
size = s + 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
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;
|
||
|
|
}
|
||
|
|
|
||
|
|
private void add(E e, Object[] elementData, int s) {
|
||
|
|
if (s == elementData.length)
|
||
|
|
elementData = grow();
|
||
|
|
elementData[s] = e;
|
||
|
|
size = s + 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
private Object[] grow() {
|
||
|
|
return grow(size + 1);
|
||
|
|
}
|
||
|
|
|
||
|
|
private Object[] grow(int minCapacity) {
|
||
|
|
int oldCapacity = elementData.length;
|
||
|
|
if (oldCapacity > 0 || elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
|
||
|
|
int newCapacity = ArrayByteList.newLength(oldCapacity,
|
||
|
|
minCapacity - oldCapacity, /* minimum growth */
|
||
|
|
oldCapacity >> 1 /* preferred growth */);
|
||
|
|
return elementData = Arrays.copyOf(elementData, newCapacity);
|
||
|
|
} else {
|
||
|
|
return elementData = new Object[Math.max(DEFAULT_CAPACITY, minCapacity)];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public static int newLength(int oldLength, int minGrowth, int prefGrowth) {
|
||
|
|
// preconditions not checked because of inlining
|
||
|
|
// assert oldLength >= 0
|
||
|
|
// assert minGrowth > 0
|
||
|
|
|
||
|
|
int prefLength = oldLength + Math.max(minGrowth, prefGrowth); // might overflow
|
||
|
|
if (0 < prefLength && prefLength <= SOFT_MAX_ARRAY_LENGTH) {
|
||
|
|
return prefLength;
|
||
|
|
} else {
|
||
|
|
// put code cold in a separate method
|
||
|
|
return hugeLength(oldLength, minGrowth);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private static int hugeLength(int oldLength, int minGrowth) {
|
||
|
|
int minLength = oldLength + minGrowth;
|
||
|
|
if (minLength < 0) { // overflow
|
||
|
|
throw new OutOfMemoryError(
|
||
|
|
"Required array length " + oldLength + " + " + minGrowth + " is too large");
|
||
|
|
} else if (minLength <= SOFT_MAX_ARRAY_LENGTH) {
|
||
|
|
return SOFT_MAX_ARRAY_LENGTH;
|
||
|
|
} else {
|
||
|
|
return minLength;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public void ensureCapacity(int minCapacity) {
|
||
|
|
if (minCapacity > elementData.length
|
||
|
|
&& !(elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
|
||
|
|
&& minCapacity <= DEFAULT_CAPACITY)) {
|
||
|
|
modCount++;
|
||
|
|
grow(minCapacity);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
@Override
|
||
|
|
public E get(int index) {
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
|
||
|
|
@Override
|
||
|
|
public int size() {
|
||
|
|
return size;
|
||
|
|
}
|
||
|
|
|
||
|
|
public int indexOf(Object o) {
|
||
|
|
return indexOfRange(o, 0, size);
|
||
|
|
}
|
||
|
|
|
||
|
|
int indexOfRange(Object o, int start, int end) {
|
||
|
|
Object[] es = elementData;
|
||
|
|
if (o == null) {
|
||
|
|
for (int i = start; i < end; i++) {
|
||
|
|
if (es[i] == null) {
|
||
|
|
return i;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
for (int i = start; i < end; i++) {
|
||
|
|
if (o.equals(es[i])) {
|
||
|
|
return i;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
public boolean isEmpty() {
|
||
|
|
return size == 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*private final E[] a;
|
||
|
|
@Override
|
||
|
|
public boolean add(E e) {
|
||
|
|
add(size(), e);
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
@Override
|
||
|
|
public int size() {
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
public Object[] toArray() {
|
||
|
|
// Estimate size of array; be prepared to see more or fewer elements
|
||
|
|
Object[] r = new Object[size()];
|
||
|
|
|
||
|
|
for (int i = 0; i < r.length; i++) {
|
||
|
|
// fewer elements than expected
|
||
|
|
Arrays.copyOf(r, i);
|
||
|
|
}
|
||
|
|
return Arrays.copyOf(r, i);
|
||
|
|
}
|
||
|
|
|
||
|
|
*/
|
||
|
|
}
|