So the implementation of such array can be like this
import java.util.AbstractList;
import java.util.List;
import java.util.RandomAccess;
public class IntArrayList extends AbstractList<Integer>
implements List<Integer> , RandomAccess /* todo , Cloneable, java.io.Serializable */{
private static final int INT_SIZE_MINUS_ONE = 15;
private static final int RIGHT_SHIFT = 4;
private int size;
private int isNull[];
private int data[];
IntArrayList(int size) {
if (size < 0) {
throw new RuntimeException("invalid size");
}
this.size = size;
isNull = new int[(size + INT_SIZE_MINUS_ONE) >>> RIGHT_SHIFT];
data = new int[size];
}
private void rangeCheck(int index) {
if (index < 0 || index >= size) {
throw new IndexOutOfBoundsException();
}
}
public Integer set(int index, Integer element) {
rangeCheck(index);
Integer oldValue = get(index);
if (element == null) {
isNull[index >>> RIGHT_SHIFT] &= ~(1 << (index & INT_SIZE_MINUS_ONE));
} else {
isNull[index >>> RIGHT_SHIFT] |= (1 << (index & INT_SIZE_MINUS_ONE));
data[index] = element;
}
return oldValue;
}
@Override
public Integer get(int index) {
rangeCheck(index);
if ((isNull[index >>> RIGHT_SHIFT] & (1 << (index & INT_SIZE_MINUS_ONE))) == 0) {
return null;
}
return new Integer(data[index]);
}
@Override
public int size() {
return size;
}
public boolean isEmpty() {
return size == 0;
}
}
It can be used anywhere as List<Integer>
Such kind of object can be useful for long term storage of information that rarely used. It will decrease fragmentation of heap at a cost of increased garbage generation on access to elements.