/*
* Copyright 2015 MiLaboratory.com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.milaboratory.util;
import java.util.Arrays;
/**
* Array list of primitive integers.
*
* @author Dmitry Bolotin
* @author Stanislav Poslavsky
*/
public final class IntArrayList implements java.io.Serializable {
int[] data;
int size = 0;
public IntArrayList() {
data = new int[10];
}
public IntArrayList(int initialCapacity) {
data = new int[initialCapacity];
}
public IntArrayList(int... data) {
this.data = data;
size = data.length;
}
private IntArrayList(int[] data, int size) {
this.data = data;
this.size = size;
}
public void clear() {
size = 0;
}
public void ensureCapacity(int minCapacity) {
int oldCapacity = data.length;
if (minCapacity > oldCapacity) {
int newCapacity = (oldCapacity * 3) / 2 + 1;
if (newCapacity < minCapacity)
newCapacity = minCapacity;
data = Arrays.copyOf(data, newCapacity);
}
}
public void add(int num) {
ensureCapacity(size + 1);
data[size++] = num;
}
public void add(int position, int num) {
if (position < 0 || position >= size)
throw new IndexOutOfBoundsException();
ensureCapacity(size + 1);
System.arraycopy(data, position, data, position + 1,
size - position);
data[position] = num;
size++;
}
public void addAll(int[] arr) {
int arrLen = arr.length;
ensureCapacity(arrLen + size);
System.arraycopy(arr, 0, data, size, arrLen);
size += arrLen;
}
public void addAll(IntArrayList intArrayList) {
int arrLen = intArrayList.size();
ensureCapacity(arrLen + size);
System.arraycopy(intArrayList.data, 0, data, size, arrLen);
size += arrLen;
}
public void set(int position, int num) {
if (position < 0 || position >= size)
throw new IndexOutOfBoundsException();
data[position] = num;
}
public void copyFrom(IntArrayList other) {
clear();
addAll(other);
}
public void sort() {
Arrays.sort(data, 0, size);
}
public void stableSort(IntComparator comparator) {
int i, j;
int key;
for (i = 1; i < size; i++) {
key = data[i];
for (j = i; j > 0 && comparator.compare(data[j - 1], key) > 0; j--) {
data[j] = data[j - 1];
}
data[j] = key;
}
}
/**
* Alias for addAll(int) method.
*
* @param value
*/
public void push(int value) {
add(value);
}
/**
* Return last element leaving it in stack.
*
* @return last element leaving it in stack
*/
public int peek() {
return data[size - 1];
}
/**
* Removes the object at the top of this stack and returns that object as the value of this function.
*
* @return pop
*/
public int pop() {
return data[--size];
}
/**
* Copies an array from the specified source array, beginning at the specified position. The number of components
* copied is equal to the length argument.
*
* @param src - the source array.
* @param fromIndex - starting position in the source array.
* @param length - the number of array elements to be copied.
*/
public void add(int[] src, int fromIndex, int length) {
ensureCapacity(size + length);
System.arraycopy(src, fromIndex, data, size, length);
size = size + length;
}
public void reverse() {
reverse(0, size);
}
public void reverse(int from, int to) {
int tmp, index1, index2, length = to - from;
for (int i = (length + 1) / 2 - 1; i >= 0; --i) {
tmp = data[index1 = from + i];
data[index1] = data[index2 = from + length - i - 1];
data[index2] = tmp;
}
}
public int get(int i) {
if (i < 0 || i >= size)
throw new IndexOutOfBoundsException("Size: " + size + " index: " + i);
return data[i];
}
public boolean replaceFirst(int from, int to) {
for (int i = 0; i < size; ++i)
if (data[i] == from) {
data[i] = to;
return true;
}
return false;
}
public boolean replaceAll(int from, int to) {
boolean replaced = false;
for (int i = 0; i < size; ++i)
if (data[i] == from) {
data[i] = to;
replaced = true;
}
return replaced;
}
public int last() {
return data[size - 1];
}
public int[] toArray() {
return Arrays.copyOfRange(data, 0, size);
}
public int size() {
return size;
}
public boolean contains(int value) {
return indexOf(value) >= 0;
}
public int indexOf(int value) {
for (int i = 0; i < size; ++i)
if (data[i] == value)
return i;
return -1;
}
public boolean isEmpty() {
return size == 0;
}
@Override
public IntArrayList clone() {
return new IntArrayList(Arrays.copyOf(data, data.length), size);
}
@Override
public boolean equals(Object obj) {
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final IntArrayList other = (IntArrayList) obj;
if (this.size != other.size)
return false;
for (int i = 0; i < size; ++i)
if (this.data[i] != other.data[i])
return false;
return true;
}
@Override
public int hashCode() {
int hash = 5;
for (int i = 0; i < size; ++i)
hash = 31 * hash + data[i];
return hash;
}
@Override
public String toString() {
int iMax = size() - 1;
if (iMax == -1)
return "[]";
StringBuilder b = new StringBuilder();
b.append('[');
for (int i = 0; ; i++) {
b.append(data[i]);
if (i == iMax)
return b.append(']').toString();
b.append(", ");
}
}
public static int[] getArrayReference(IntArrayList list) {
return list.data;
}
public interface IntComparator {
int compare(int i1, int i2);
}
}