/* * Twidere - Twitter client for Android * * Copyright (C) 2012-2015 Mariotaku Lee * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ /* * Created on Nov 21, 2005 */ package jopt.csp.util; import org.apache.commons.collections.primitives.ArrayIntList; import org.apache.commons.collections.primitives.IntCollection; import org.apache.commons.collections.primitives.IntList; import org.apache.commons.collections.primitives.RandomAccessIntList; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.util.Arrays; /** * A flexible, sortable list of int primitives. Borrows much * of its functionality from the ArrayIntList implementation * given in the Commons Primitives project * (http://jakarta.apache.org/commons/primitives/index.html) * * @author Chris Johnson */ public class SortableIntList extends RandomAccessIntList implements IntList, Serializable { private transient int[] data = null; private int size = 0; /** * Construct an empty list with the default * initial capacity. */ public SortableIntList() { this(8); } /** * Construct an empty list with the given * initial capacity. * * @throws IllegalArgumentException when initialCapacity is negative */ public SortableIntList(int initialCapacity) { if (initialCapacity < 0) { throw new IllegalArgumentException("capacity " + initialCapacity + " cannot be negative"); } data = new int[initialCapacity]; size = 0; } /** * Constructs a list containing the elements of the given collection, * in the order they are returned by that collection's iterator. * * @param that the non-null collection of ints * to add * @throws NullPointerException if that is null * @see ArrayIntList#addAll(org.apache.commons.collections.primitives.IntCollection) */ public SortableIntList(IntCollection that) { this(that.size()); addAll(that); } @Override public int get(int index) { checkRange(index); return data[index]; } @Override public int size() { return size; } /** * Removes the element at the specified position in * (optional operation). Any subsequent elements * are shifted to the left, subtracting one from their * indices. Returns the element that was removed. * * @param index the index of the element to remove * @return the value of the element that was removed * @throws UnsupportedOperationException when this operation is not * supported * @throws IndexOutOfBoundsException if the specified index is out of range */ @Override public int removeElementAt(int index) { checkRange(index); incrModCount(); int oldval = data[index]; int numtomove = size - index - 1; if (numtomove > 0) { System.arraycopy(data, index + 1, data, index, numtomove); } size--; return oldval; } /** * Replaces the element at the specified * position in me with the specified element * (optional operation). If specified index is * beyond the current size, the list grows * to accommodate it. No IndexOutOfBoundsException * will occur during the set operation. * * @param index the index of the element to change * @param element the value to be stored at the specified position * @return the value previously stored at the specified position * @throws UnsupportedOperationException when this operation is not * supported */ @Override public int set(int index, int element) { ensureCapacity(index + 1); ensureSize(index + 1); incrModCount(); int oldval = data[index]; data[index] = element; return oldval; } /** * Inserts the specified element at the specified position * (optional operation). Shifts the element currently * at that position (if any) and any subsequent elements to the * right, increasing their indices. If the specified index is * beyond the current size, this method behaves like a call * to {@link #set(int, int)}. * * @param index the index at which to insert the element * @param element the value to insert * @throws UnsupportedOperationException when this operation is not * supported * @throws IllegalArgumentException if some aspect of the specified element * prevents it from being added to me */ @Override public void add(int index, int element) { if (index >= size) { set(index, element); } else { incrModCount(); ensureCapacity(size + 1); int numtomove = size - index; System.arraycopy(data, index, data, index + 1, numtomove); data[index] = element; size++; } } /** * Increases my capacity, if necessary, to ensure that I can hold at * least the number of elements specified by the minimum capacity * argument without growing. */ public void ensureCapacity(int mincap) { incrModCount(); if (mincap > data.length) { int newcap = (data.length * 3) / 2 + 1; int[] olddata = data; data = new int[newcap < mincap ? mincap : newcap]; System.arraycopy(olddata, 0, data, 0, size); } } /** * Reduce my capacity, if necessary, to match my * current {@link #size size}. */ public void trimToSize() { incrModCount(); if (size < data.length) { int[] olddata = data; data = new int[size]; System.arraycopy(olddata, 0, data, 0, size); } } /** * Sorts the list into ascending numerical order via {@link java.util.Arrays#sort(int[])} *

* Sorts the list of ints into ascending numerical order. The sorting algorithm * is a tuned quicksort, adapted from Jon L. Bentley and M. Douglas McIlroy's "Engineering * a Sort Function", Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November * 1993). This algorithm offers n*log(n) performance on many data sets that cause other * quicksorts to degrade to quadratic performance. */ public void sort() { trimToSize(); Arrays.sort(data); } /** * Reverses the order of the elements */ public void reverse() { for (int i = 0, mid = size >> 1, j = size - 1; i < mid; i++, j--) swap(i, j); } /** * Swaps the two specified elements. * (If the specified positions are equal, invoking this method leaves * the list unchanged.) */ public void swap(int i, int j) { int tmp = data[i]; data[i] = data[j]; data[j] = tmp; } /** * Searches the list for the specified key via {@link java.util.Arrays#binarySearch(int[], int)} *

* The array must be sorted (as by the sort method, above) prior to making this call. * If it is not sorted, the results are undefined. If the list contains multiple elements * with the specified value, there is no guarantee which one will be found. * * @param key the value to be searched for * @return index of the search key, if it is contained in the list; otherwise, (-(insertion point) - 1) */ public int binarySearch(int key) { trimToSize(); return Arrays.binarySearch(data, key); } /** * Sorts the specified range of the list into ascending numerical order * via {@link java.util.Arrays#sort(int[], int, int)} * * @param fromIndex the index of the first element (inclusive) to be sorted * @param toIndex the index of the last element (exclusive) to be sorted */ public void sort(int fromIndex, int toIndex) { trimToSize(); Arrays.sort(data, fromIndex, toIndex); } private void writeObject(ObjectOutputStream out) throws IOException { out.defaultWriteObject(); out.writeInt(data.length); for (int i = 0; i < size; i++) { out.writeInt(data[i]); } } private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); data = new int[in.readInt()]; for (int i = 0; i < size; i++) { data[i] = in.readInt(); } } private void ensureSize(int potentialSize) { if (potentialSize > size) { size = potentialSize; } } private void checkRange(int index) { if (index < 0 || index >= size) { throw new IndexOutOfBoundsException("Should be at least 0 and less than " + size + ", found " + index); } } }