Java tutorial
package android.support.v4.util; public class SparseArrayCompat<E> implements Cloneable { private static final Object DELETED; private boolean mGarbage; private int[] mKeys; private int mSize; private Object[] mValues; static { DELETED = new Object(); } public SparseArrayCompat() { this(10); } public SparseArrayCompat(int i) { this.mGarbage = false; if (i == 0) { this.mKeys = ContainerHelpers.EMPTY_INTS; this.mValues = ContainerHelpers.EMPTY_OBJECTS; } else { int idealIntArraySize = ContainerHelpers.idealIntArraySize(i); this.mKeys = new int[idealIntArraySize]; this.mValues = new Object[idealIntArraySize]; } this.mSize = 0; } public SparseArrayCompat<E> clone() { try { SparseArrayCompat<E> sparseArrayCompat = (SparseArrayCompat) super.clone(); try { sparseArrayCompat.mKeys = (int[]) this.mKeys.clone(); sparseArrayCompat.mValues = (Object[]) this.mValues.clone(); return sparseArrayCompat; } catch (CloneNotSupportedException e) { return sparseArrayCompat; } } catch (CloneNotSupportedException e2) { return null; } } public E get(int i) { return get(i, null); } public E get(int i, E e) { int binarySearch = ContainerHelpers.binarySearch(this.mKeys, this.mSize, i); return (binarySearch < 0 || this.mValues[binarySearch] == DELETED) ? e : this.mValues[binarySearch]; } public void delete(int i) { int binarySearch = ContainerHelpers.binarySearch(this.mKeys, this.mSize, i); if (binarySearch >= 0 && this.mValues[binarySearch] != DELETED) { this.mValues[binarySearch] = DELETED; this.mGarbage = true; } } public void remove(int i) { delete(i); } public void removeAt(int i) { if (this.mValues[i] != DELETED) { this.mValues[i] = DELETED; this.mGarbage = true; } } public void removeAtRange(int i, int i2) { int min = Math.min(this.mSize, i + i2); while (i < min) { removeAt(i); i++; } } private void gc() { int i = this.mSize; int[] iArr = this.mKeys; Object[] objArr = this.mValues; int i2 = 0; for (int i3 = 0; i3 < i; i3++) { Object obj = objArr[i3]; if (obj != DELETED) { if (i3 != i2) { iArr[i2] = iArr[i3]; objArr[i2] = obj; objArr[i3] = null; } i2++; } } this.mGarbage = false; this.mSize = i2; } public void put(int i, E e) { int binarySearch = ContainerHelpers.binarySearch(this.mKeys, this.mSize, i); if (binarySearch >= 0) { this.mValues[binarySearch] = e; return; } binarySearch ^= -1; if (binarySearch >= this.mSize || this.mValues[binarySearch] != DELETED) { if (this.mGarbage && this.mSize >= this.mKeys.length) { gc(); binarySearch = ContainerHelpers.binarySearch(this.mKeys, this.mSize, i) ^ -1; } if (this.mSize >= this.mKeys.length) { int idealIntArraySize = ContainerHelpers.idealIntArraySize(this.mSize + 1); Object obj = new int[idealIntArraySize]; Object obj2 = new Object[idealIntArraySize]; System.arraycopy(this.mKeys, 0, obj, 0, this.mKeys.length); System.arraycopy(this.mValues, 0, obj2, 0, this.mValues.length); this.mKeys = obj; this.mValues = obj2; } if (this.mSize - binarySearch != 0) { System.arraycopy(this.mKeys, binarySearch, this.mKeys, binarySearch + 1, this.mSize - binarySearch); System.arraycopy(this.mValues, binarySearch, this.mValues, binarySearch + 1, this.mSize - binarySearch); } this.mKeys[binarySearch] = i; this.mValues[binarySearch] = e; this.mSize++; return; } this.mKeys[binarySearch] = i; this.mValues[binarySearch] = e; } public int size() { if (this.mGarbage) { gc(); } return this.mSize; } public int keyAt(int i) { if (this.mGarbage) { gc(); } return this.mKeys[i]; } public E valueAt(int i) { if (this.mGarbage) { gc(); } return this.mValues[i]; } public void setValueAt(int i, E e) { if (this.mGarbage) { gc(); } this.mValues[i] = e; } public int indexOfKey(int i) { if (this.mGarbage) { gc(); } return ContainerHelpers.binarySearch(this.mKeys, this.mSize, i); } public int indexOfValue(E e) { if (this.mGarbage) { gc(); } for (int i = 0; i < this.mSize; i++) { if (this.mValues[i] == e) { return i; } } return -1; } public void clear() { int i = this.mSize; Object[] objArr = this.mValues; for (int i2 = 0; i2 < i; i2++) { objArr[i2] = null; } this.mSize = 0; this.mGarbage = false; } public void append(int i, E e) { if (this.mSize == 0 || i > this.mKeys[this.mSize - 1]) { if (this.mGarbage && this.mSize >= this.mKeys.length) { gc(); } int i2 = this.mSize; if (i2 >= this.mKeys.length) { int idealIntArraySize = ContainerHelpers.idealIntArraySize(i2 + 1); Object obj = new int[idealIntArraySize]; Object obj2 = new Object[idealIntArraySize]; System.arraycopy(this.mKeys, 0, obj, 0, this.mKeys.length); System.arraycopy(this.mValues, 0, obj2, 0, this.mValues.length); this.mKeys = obj; this.mValues = obj2; } this.mKeys[i2] = i; this.mValues[i2] = e; this.mSize = i2 + 1; return; } put(i, e); } public String toString() { if (size() <= 0) { return "{}"; } StringBuilder stringBuilder = new StringBuilder(this.mSize * 28); stringBuilder.append('{'); for (int i = 0; i < this.mSize; i++) { if (i > 0) { stringBuilder.append(", "); } stringBuilder.append(keyAt(i)); stringBuilder.append('='); SparseArrayCompat valueAt = valueAt(i); if (valueAt != this) { stringBuilder.append(valueAt); } else { stringBuilder.append("(this Map)"); } } stringBuilder.append('}'); return stringBuilder.toString(); } }