Add IntList a list implementation for primitive integers.

This commit is contained in:
2017-02-03 20:31:58 +01:00
parent d3315a80d5
commit 145c2152d0
12 changed files with 1079 additions and 0 deletions

View File

@@ -0,0 +1,313 @@
package org.lucares.collections;
import java.util.List;
/**
* A list for primitive ints.
* <p>
* This class does not (yet) implements all methods a java.util {@link List}
* would have.
*/
public class IntList {
private static final int DEFAULT_CAPACITY = 10;
private int[] data;
private int index = 0;
/**
* Create a new {@link IntList} with initial capacity 10.
*/
public IntList() {
this(DEFAULT_CAPACITY);
}
/**
* Create a new {@link IntList}.
*
* @param initialCapacity
* initial capacity
* @throws IllegalArgumentException
* if initial capacity is negative
*/
public IntList(final int initialCapacity) {
if (initialCapacity < 0) {
throw new IllegalArgumentException("initial capacity must not be negative");
}
data = new int[initialCapacity];
}
/**
* Create a new {@link IntList} with a copy of the elements of
* {@code intList}.
*
* @param intList
* the list to copy
*/
public IntList(final IntList intList) {
data = new int[intList.getCapacity()];
System.arraycopy(intList.data, 0, data, 0, intList.size());
index = intList.size();
}
/**
* Returns {@code true} if this list contains no elements.
*
* @return {@code true} if this list contains no elements
*/
public boolean isEmpty() {
return index == 0;
}
/**
* Returns the number of elements in this list.
*
* @return the number of elements in this list
*/
public int size() {
return index;
}
/**
* Returns the number of elements this list can hold before a resize is
* necessary.
*
* @return the number of elements this list can hold before a resize is
* necessary
*/
public int getCapacity() {
return data.length;
}
/**
* Adds {@code value} to the list.
*
* @param value
* the value to add
*/
public void add(final int value) {
addAll(value);
}
/**
* Inserts {@code values} at position {@code pos} into the list.
*
* @param pos
* the position to insert the elements
* @param values
* the elements to insert
* @throws IndexOutOfBoundsException
* if pos is out of bounds {@code pos < 0 || pos > size()}
* @throws NullPointerException
* if {@code values} is {@code null}
*/
public void insert(final int pos, final int... values) {
if (pos < 0) {
throw new IndexOutOfBoundsException("pos must not be negative, but was: " + pos);
}
if (pos > index) {
throw new IndexOutOfBoundsException("pos must not smaller than size(), but was: " + pos);
}
if (values == null) {
throw new NullPointerException("values parameter must not be null");
}
ensureCapacity(values.length);
final int[] newData = new int[data.length];
System.arraycopy(data, 0, newData, 0, pos);
System.arraycopy(values, 0, newData, pos, values.length);
System.arraycopy(data, pos, newData, pos + values.length, index - pos);
data = newData;
index += values.length;
}
/**
* Set the value {@code value} at position {@code pos}.
*
* @param pos
* the position to overwrite
* @param value
* the new value
* @throws IndexOutOfBoundsException
* if pos is out of bounds {@code pos < 0 || pos >= size()}
*/
public void set(final int pos, final int value) {
if (pos < 0) {
throw new IndexOutOfBoundsException("pos must not be negative, but was: " + pos);
}
if (pos >= index) {
throw new IndexOutOfBoundsException("pos must not smaller than size(), but was: " + pos);
}
data[pos] = value;
}
/**
* Add {@code values} to the list.
*
* @param values
* the values to add
* @throws NullPointerException
* if {@code values} is {@code null}
*/
public void addAll(final int... values) {
ensureCapacity(values.length);
System.arraycopy(values, 0, data, index, values.length);
index += values.length;
}
/**
* Removes elements from the list.
*
* @param from
* index of the first element to remove
* @param length
* number of elements to remove
* @throws IndexOutOfBoundsException
* if {@code from} or {@code length} is negative, or if the
* range defined by {@code from} and {@code length} is out of
* bounds
*/
public void remove(final int from, final int length) {
if (from < 0) {
throw new IndexOutOfBoundsException("from must not be negative, but was: " + from);
}
if (length < 0) {
throw new IndexOutOfBoundsException("length must not be negative, but was: " + length);
}
if (from + length > index) {
throw new IndexOutOfBoundsException("from: " + from + " length: " + length);
}
final int[] newData = new int[data.length];
System.arraycopy(data, 0, newData, 0, from);
System.arraycopy(data, from + length, newData, from, data.length - from - length);
data = newData;
index -= length;
}
/**
* Returns the element at position {@code pos}.
*
* @param pos
* position of the element to return
* @return the element at position {@code pos}
* @throws IndexOutOfBoundsException
* if {@code pos} is out of bounds
* {@code index < 0 || index >= size()}
*/
public int get(final int pos) {
if (pos < 0 || pos >= index) {
throw new IndexOutOfBoundsException();
}
return data[pos];
}
/**
* Returns the {@code length} elements starting at {@code from}.
*
* @param from
* position of the first element
* @param length
* number of elements
* @return the {@code length} elements starting at {@code from}
* @throws IndexOutOfBoundsException
* if {@code from} or {@code length} is negative, or if the
* range defined by {@code from} and {@code length} is out of
* bounds
*/
public int[] get(final int from, final int length) {
if (from < 0) {
throw new IndexOutOfBoundsException("from must not be negative, but was: " + from);
}
if (length < 0) {
throw new IndexOutOfBoundsException("length must not be negative, but was: " + length);
}
if (from + length > index) {
throw new IndexOutOfBoundsException("from: " + from + " length: " + length);
}
final int[] result = new int[length];
System.arraycopy(data, from, result, 0, length);
return result;
}
/**
* Returns an array containing all elements of this list.
*
* @return an array containing all elements of this list
*/
public int[] toArray() {
return get(0, index);
}
private void ensureCapacity(final int newElements) {
final int requiredCapacity = index + newElements;
if (requiredCapacity - 1 >= data.length) {
final int newCapacity = data.length * 2 > requiredCapacity ? data.length * 2 : requiredCapacity;
final int[] newData = new int[newCapacity];
System.arraycopy(data, 0, newData, 0, index);
data = newData;
}
}
/**
* Reduces the capacity to the size of the list.
* <p>
* Call this method to reduce the memory consumption of this list.
*/
public void trim() {
final int[] newData = new int[index];
System.arraycopy(data, 0, newData, 0, index);
data = newData;
}
@Override
public int hashCode() {
if (index == 0) {
return 0;
}
int result = 1;
for (int i = 0; i < index; i++) {
result = 31 * result + data[i];
}
return result;
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final IntList other = (IntList) obj;
if (index != other.index) {
return false;
}
for (int i = 0; i < index; i++) {
if (data[i] != other.data[i]) {
return false;
}
}
return true;
}
}