com.gs.collections.impl.list.mutable.FastList Maven / Gradle / Ivy
Show all versions of gs-collections Show documentation
/*
* Copyright 2015 Goldman Sachs.
*
* 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.gs.collections.impl.list.mutable;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.RandomAccess;
import com.gs.collections.api.block.HashingStrategy;
import com.gs.collections.api.block.function.Function;
import com.gs.collections.api.block.function.Function0;
import com.gs.collections.api.block.function.Function2;
import com.gs.collections.api.block.function.Function3;
import com.gs.collections.api.block.function.primitive.BooleanFunction;
import com.gs.collections.api.block.function.primitive.ByteFunction;
import com.gs.collections.api.block.function.primitive.CharFunction;
import com.gs.collections.api.block.function.primitive.DoubleFunction;
import com.gs.collections.api.block.function.primitive.DoubleObjectToDoubleFunction;
import com.gs.collections.api.block.function.primitive.FloatFunction;
import com.gs.collections.api.block.function.primitive.FloatObjectToFloatFunction;
import com.gs.collections.api.block.function.primitive.IntFunction;
import com.gs.collections.api.block.function.primitive.IntObjectToIntFunction;
import com.gs.collections.api.block.function.primitive.LongFunction;
import com.gs.collections.api.block.function.primitive.LongObjectToLongFunction;
import com.gs.collections.api.block.function.primitive.ShortFunction;
import com.gs.collections.api.block.predicate.Predicate;
import com.gs.collections.api.block.predicate.Predicate2;
import com.gs.collections.api.block.procedure.Procedure;
import com.gs.collections.api.block.procedure.Procedure2;
import com.gs.collections.api.block.procedure.primitive.ObjectIntProcedure;
import com.gs.collections.api.collection.primitive.MutableBooleanCollection;
import com.gs.collections.api.collection.primitive.MutableByteCollection;
import com.gs.collections.api.collection.primitive.MutableCharCollection;
import com.gs.collections.api.collection.primitive.MutableDoubleCollection;
import com.gs.collections.api.collection.primitive.MutableFloatCollection;
import com.gs.collections.api.collection.primitive.MutableIntCollection;
import com.gs.collections.api.collection.primitive.MutableLongCollection;
import com.gs.collections.api.collection.primitive.MutableShortCollection;
import com.gs.collections.api.list.MutableList;
import com.gs.collections.api.list.primitive.MutableBooleanList;
import com.gs.collections.api.list.primitive.MutableByteList;
import com.gs.collections.api.list.primitive.MutableCharList;
import com.gs.collections.api.list.primitive.MutableDoubleList;
import com.gs.collections.api.list.primitive.MutableFloatList;
import com.gs.collections.api.list.primitive.MutableIntList;
import com.gs.collections.api.list.primitive.MutableLongList;
import com.gs.collections.api.list.primitive.MutableShortList;
import com.gs.collections.api.map.MutableMap;
import com.gs.collections.api.map.primitive.ObjectDoubleMap;
import com.gs.collections.api.map.primitive.ObjectLongMap;
import com.gs.collections.api.multimap.MutableMultimap;
import com.gs.collections.api.ordered.OrderedIterable;
import com.gs.collections.api.partition.list.PartitionMutableList;
import com.gs.collections.api.tuple.Twin;
import com.gs.collections.impl.block.factory.Comparators;
import com.gs.collections.impl.block.factory.Predicates2;
import com.gs.collections.impl.block.factory.Procedures2;
import com.gs.collections.impl.list.mutable.primitive.BooleanArrayList;
import com.gs.collections.impl.list.mutable.primitive.ByteArrayList;
import com.gs.collections.impl.list.mutable.primitive.CharArrayList;
import com.gs.collections.impl.list.mutable.primitive.DoubleArrayList;
import com.gs.collections.impl.list.mutable.primitive.FloatArrayList;
import com.gs.collections.impl.list.mutable.primitive.IntArrayList;
import com.gs.collections.impl.list.mutable.primitive.LongArrayList;
import com.gs.collections.impl.list.mutable.primitive.ShortArrayList;
import com.gs.collections.impl.map.mutable.UnifiedMap;
import com.gs.collections.impl.multimap.list.FastListMultimap;
import com.gs.collections.impl.parallel.BatchIterable;
import com.gs.collections.impl.partition.list.PartitionFastList;
import com.gs.collections.impl.utility.ArrayIterate;
import com.gs.collections.impl.utility.ArrayListIterate;
import com.gs.collections.impl.utility.Iterate;
import com.gs.collections.impl.utility.ListIterate;
import com.gs.collections.impl.utility.internal.InternalArrayIterate;
import com.gs.collections.impl.utility.internal.RandomAccessListIterate;
import net.jcip.annotations.NotThreadSafe;
/**
* FastList is an attempt to provide the same functionality as ArrayList without the support for concurrent
* modification exceptions. It also attempts to correct the problem with subclassing ArrayList
* in that the data elements are protected, not private. It is this issue that caused this class
* to be created in the first place. The intent was to provide optimized internal iterators which use direct access
* against the array of items, which is currently not possible by subclassing ArrayList.
*
* An empty FastList created by calling the default constructor starts with a shared reference to a static
* empty array (DEFAULT_SIZED_EMPTY_ARRAY). This makes empty FastLists very memory efficient. The
* first call to add will lazily create an array of size 10.
*
* An empty FastList created by calling the pre-size constructor with a value of 0 (new FastList(0)) starts
* with a shared reference to a static empty array (ZERO_SIZED_ARRAY). This makes FastLists presized to 0 very
* memory efficient as well. The first call to add will lazily create an array of size 1.
*/
@NotThreadSafe
public class FastList
extends AbstractMutableList
implements Externalizable, RandomAccess, BatchIterable
{
private static final long serialVersionUID = 1L;
private static final Object[] DEFAULT_SIZED_EMPTY_ARRAY = {};
private static final Object[] ZERO_SIZED_ARRAY = {};
private static final int MAXIMUM_ARRAY_SIZE = Integer.MAX_VALUE - 8;
protected int size;
protected transient T[] items = (T[]) DEFAULT_SIZED_EMPTY_ARRAY;
public FastList()
{
}
public FastList(int initialCapacity)
{
this.items = initialCapacity == 0 ? (T[]) ZERO_SIZED_ARRAY : (T[]) new Object[initialCapacity];
}
protected FastList(T[] array)
{
this(array.length, array);
}
protected FastList(int size, T[] array)
{
this.size = size;
this.items = array;
}
public FastList(Collection extends T> source)
{
this.items = (T[]) source.toArray();
this.size = this.items.length;
}
public static FastList newList()
{
return new FastList();
}
public static FastList wrapCopy(E... array)
{
E[] newArray = (E[]) new Object[array.length];
System.arraycopy(array, 0, newArray, 0, array.length);
return new FastList(newArray);
}
public static FastList newList(int initialCapacity)
{
return new FastList(initialCapacity);
}
public static FastList newList(Iterable extends E> source)
{
return FastList.newListWith((E[]) Iterate.toArray(source));
}
/**
* Creates a new list using the passed {@code elements} argument as the backing store.
*
* !!! WARNING: This method uses the passed in array, so can be very unsafe if the original
* array is held onto anywhere else. !!!
*/
public static FastList newListWith(E... elements)
{
return new FastList(elements);
}
/**
* Creates a new FastList pre-sized to the specified size filled with default values generated by the specified function.
*
* @since 3.0
*/
public static FastList newWithNValues(int size, Function0 factory)
{
FastList newFastList = FastList.newList(size);
for (int i = 0; i < size; i++)
{
newFastList.add(factory.value());
}
return newFastList;
}
@Override
public FastList clone()
{
FastList result = (FastList) super.clone();
if (this.items.length > 0)
{
result.items = this.items.clone();
}
return result;
}
public void clear()
{
Arrays.fill(this.items, null);
this.size = 0;
}
@Override
public void forEach(int from, int to, Procedure super T> procedure)
{
ListIterate.rangeCheck(from, to, this.size);
InternalArrayIterate.forEachWithoutChecks(this.items, from, to, procedure);
}
@Override
public void forEachWithIndex(int from, int to, ObjectIntProcedure super T> objectIntProcedure)
{
ListIterate.rangeCheck(from, to, this.size);
InternalArrayIterate.forEachWithIndexWithoutChecks(this.items, from, to, objectIntProcedure);
}
public void batchForEach(Procedure super T> procedure, int sectionIndex, int sectionCount)
{
InternalArrayIterate.batchForEach(procedure, this.items, this.size, sectionIndex, sectionCount);
}
public int getBatchCount(int batchSize)
{
return Math.max(1, this.size() / batchSize);
}
public E[] toArray(E[] array, int sourceFromIndex, int sourceToIndex, int destinationIndex)
{
System.arraycopy(this.items, sourceFromIndex, array, destinationIndex, sourceToIndex - sourceFromIndex + 1);
return array;
}
public E[] toArray(int sourceFromIndex, int sourceToIndex)
{
return this.toArray((E[]) new Object[sourceToIndex - sourceFromIndex + 1], sourceFromIndex, sourceToIndex, 0);
}
@Override
public FastList sortThis(Comparator super T> comparator)
{
Arrays.sort(this.items, 0, this.size, comparator);
return this;
}
@Override
public FastList sortThis()
{
Arrays.sort(this.items, 0, this.size);
return this;
}
@Override
public FastList reverseThis()
{
ArrayIterate.reverse(this.items, this.size);
return this;
}
@Override
public boolean addAll(Collection extends T> source)
{
if (source.isEmpty())
{
return false;
}
if (source.getClass() == FastList.class)
{
this.addAllFastList((FastList) source);
}
else if (source.getClass() == ArrayList.class)
{
this.addAllArrayList((ArrayList) source);
}
else if (source instanceof List && source instanceof RandomAccess)
{
this.addAllRandomAccessList((List) source);
}
else
{
this.addAllCollection(source);
}
return true;
}
private void addAllFastList(FastList source)
{
int sourceSize = source.size();
int newSize = this.size + sourceSize;
this.ensureCapacity(newSize);
System.arraycopy(source.items, 0, this.items, this.size, sourceSize);
this.size = newSize;
}
private void addAllArrayList(ArrayList source)
{
int sourceSize = source.size();
int newSize = this.size + sourceSize;
this.ensureCapacity(newSize);
ArrayListIterate.toArray(source, this.items, this.size, sourceSize);
this.size = newSize;
}
private void addAllRandomAccessList(List source)
{
int sourceSize = source.size();
int newSize = this.size + sourceSize;
this.ensureCapacity(newSize);
RandomAccessListIterate.toArray(source, this.items, this.size, sourceSize);
this.size = newSize;
}
private void addAllCollection(Collection extends T> source)
{
this.ensureCapacity(this.size + source.size());
Iterate.forEachWith(source, Procedures2.addToCollection(), this);
}
@Override
public boolean containsAll(Collection> source)
{
return Iterate.allSatisfyWith(source, Predicates2.in(), this);
}
@Override
public boolean containsAllArguments(Object... source)
{
return ArrayIterate.allSatisfyWith(source, Predicates2.in(), this);
}
@Override
public E[] toArray(E[] array)
{
if (array.length < this.size)
{
array = (E[]) Array.newInstance(array.getClass().getComponentType(), this.size);
}
System.arraycopy(this.items, 0, array, 0, this.size);
if (array.length > this.size)
{
array[this.size] = null;
}
return array;
}
@Override
public Object[] toArray()
{
return this.copyItemsWithNewCapacity(this.size);
}
public T[] toTypedArray(Class clazz)
{
T[] array = (T[]) Array.newInstance(clazz, this.size);
System.arraycopy(this.items, 0, array, 0, this.size);
return array;
}
private void throwOutOfBounds(int index)
{
throw this.newIndexOutOfBoundsException(index);
}
public T set(int index, T element)
{
T previous = this.get(index);
this.items[index] = element;
return previous;
}
@Override
public int indexOf(Object object)
{
return InternalArrayIterate.indexOf(this.items, this.size, object);
}
@Override
public int lastIndexOf(Object object)
{
return InternalArrayIterate.lastIndexOf(this.items, this.size, object);
}
public void trimToSize()
{
if (this.size < this.items.length)
{
this.transferItemsToNewArrayWithCapacity(this.size);
}
}
/**
* Express load factor as 0.25 to trim a collection with more than 25% excess capacity
*/
public boolean trimToSizeIfGreaterThanPercent(double loadFactor)
{
double excessCapacity = 1.0 - (double) this.size / (double) this.items.length;
if (excessCapacity > loadFactor)
{
this.trimToSize();
return true;
}
return false;
}
public void ensureCapacity(int minCapacity)
{
int oldCapacity = this.items.length;
if (minCapacity > oldCapacity)
{
int newCapacity = Math.max(this.sizePlusFiftyPercent(oldCapacity), minCapacity);
this.transferItemsToNewArrayWithCapacity(newCapacity);
}
}
private void transferItemsToNewArrayWithCapacity(int newCapacity)
{
this.items = (T[]) this.copyItemsWithNewCapacity(newCapacity);
}
private Object[] copyItemsWithNewCapacity(int newCapacity)
{
Object[] newItems = new Object[newCapacity];
System.arraycopy(this.items, 0, newItems, 0, Math.min(this.size, newCapacity));
return newItems;
}
public FastList with(T element1, T element2)
{
this.add(element1);
this.add(element2);
return this;
}
public FastList with(T element1, T element2, T element3)
{
this.add(element1);
this.add(element2);
this.add(element3);
return this;
}
public FastList with(T... elements)
{
return this.withArrayCopy(elements, 0, elements.length);
}
public FastList withArrayCopy(T[] elements, int begin, int length)
{
this.ensureCapacity(this.size + length);
System.arraycopy(elements, begin, this.items, this.size, length);
this.size += length;
return this;
}
@Override
public T getFirst()
{
return this.isEmpty() ? null : this.items[0];
}
@Override
public T getLast()
{
return this.isEmpty() ? null : this.items[this.size() - 1];
}
@Override
public FastListMultimap groupBy(Function super T, ? extends V> function)
{
return this.groupBy(function, FastListMultimap.newMultimap());
}
@Override
public > R groupBy(Function super T, ? extends V> function, R target)
{
return InternalArrayIterate.groupBy(this.items, this.size, function, target);
}
@Override
public FastListMultimap groupByEach(Function super T, ? extends Iterable> function)
{
return this.groupByEach(function, FastListMultimap.newMultimap());
}
@Override
public > R groupByEach(
Function super T, ? extends Iterable> function,
R target)
{
return InternalArrayIterate.groupByEach(this.items, this.size, function, target);
}
@Override
public MutableMap groupByUniqueKey(Function super T, ? extends K> function)
{
return this.groupByUniqueKey(function, UnifiedMap.newMap());
}
@Override
public > R groupByUniqueKey(Function super T, ? extends K> function, R target)
{
return InternalArrayIterate.groupByUniqueKey(this.items, this.size, function, target);
}
@Override
public void appendString(Appendable appendable, String start, String separator, String end)
{
InternalArrayIterate.appendString(this, this.items, this.size, appendable, start, separator, end);
}
@Override
public MutableList take(int count)
{
return RandomAccessListIterate.take(this, count);
}
@Override
public MutableList drop(int count)
{
return RandomAccessListIterate.drop(this, count);
}
@Override
public PartitionFastList partition(Predicate super T> predicate)
{
return InternalArrayIterate.partition(this.items, this.size, predicate);
}
@Override
public PartitionFastList partitionWith(Predicate2 super T, ? super P> predicate, P parameter)
{
return InternalArrayIterate.partitionWith(this.items, this.size, predicate, parameter);
}
@Override
public void each(Procedure super T> procedure)
{
for (int i = 0; i < this.size; i++)
{
procedure.value(this.items[i]);
}
}
public void forEachIf(Predicate super T> predicate, Procedure super T> procedure)
{
for (int i = 0; i < this.size; i++)
{
T item = this.items[i];
if (predicate.accept(item))
{
procedure.value(item);
}
}
}
@Override
public void forEachWithIndex(ObjectIntProcedure super T> objectIntProcedure)
{
InternalArrayIterate.forEachWithIndex(this.items, this.size, objectIntProcedure);
}
@Override
public void forEachWith(Procedure2 super T, ? super P> procedure, P parameter)
{
for (int i = 0; i < this.size; i++)
{
procedure.value(this.items[i], parameter);
}
}
@Override
public FastList select(Predicate super T> predicate)
{
return this.select(predicate, FastList.newList());
}
@Override
public > R select(Predicate super T> predicate, R target)
{
return InternalArrayIterate.select(this.items, this.size, predicate, target);
}
@Override
public FastList selectWith(Predicate2 super T, ? super P> predicate, P parameter)
{
return this.selectWith(predicate, parameter, FastList.newList());
}
@Override
public > R selectWith(
Predicate2 super T, ? super P> predicate,
P parameter,
R target)
{
return InternalArrayIterate.selectWith(this.items, this.size, predicate, parameter, target);
}
@Override
public FastList reject(Predicate super T> predicate)
{
return this.reject(predicate, FastList.newList());
}
@Override
public > R reject(Predicate super T> predicate, R target)
{
return InternalArrayIterate.reject(this.items, this.size, predicate, target);
}
@Override
public FastList rejectWith(Predicate2 super T, ? super P> predicate, P parameter)
{
return this.rejectWith(predicate, parameter, FastList.newList());
}
@Override
public > R rejectWith(
Predicate2 super T, ? super P> predicate,
P parameter,
R target)
{
return InternalArrayIterate.rejectWith(this.items, this.size, predicate, parameter, target);
}
@Override
public
Twin> selectAndRejectWith(
Predicate2 super T, ? super P> predicate,
P parameter)
{
return InternalArrayIterate.selectAndRejectWith(this.items, this.size, predicate, parameter);
}
@Override
public FastList selectInstancesOf(Class clazz)
{
return InternalArrayIterate.selectInstancesOf(this.items, this.size, clazz);
}
@Override
public boolean removeIf(Predicate super T> predicate)
{
int currentFilledIndex = 0;
for (int i = 0; i < this.size; i++)
{
T item = this.items[i];
if (!predicate.accept(item))
{
// keep it
if (currentFilledIndex != i)
{
this.items[currentFilledIndex] = item;
}
currentFilledIndex++;
}
}
boolean changed = currentFilledIndex < this.size;
this.wipeAndResetTheEnd(currentFilledIndex);
return changed;
}
private void wipeAndResetTheEnd(int newCurrentFilledIndex)
{
for (int i = newCurrentFilledIndex; i < this.size; i++)
{
this.items[i] = null;
}
this.size = newCurrentFilledIndex;
}
@Override
public boolean removeIfWith(Predicate2 super T, ? super P> predicate, P parameter)
{
int currentFilledIndex = 0;
for (int i = 0; i < this.size; i++)
{
T item = this.items[i];
if (!predicate.accept(item, parameter))
{
// keep it
if (currentFilledIndex != i)
{
this.items[currentFilledIndex] = item;
}
currentFilledIndex++;
}
}
boolean changed = currentFilledIndex < this.size;
this.wipeAndResetTheEnd(currentFilledIndex);
return changed;
}
@Override
public FastList collect(Function super T, ? extends V> function)
{
return this.collect(function, FastList.newList(this.size()));
}
@Override
public MutableBooleanList collectBoolean(BooleanFunction super T> booleanFunction)
{
return this.collectBoolean(booleanFunction, new BooleanArrayList(this.size));
}
@Override
public R collectBoolean(BooleanFunction super T> booleanFunction, R target)
{
for (int i = 0; i < this.size; i++)
{
target.add(booleanFunction.booleanValueOf(this.items[i]));
}
return target;
}
@Override
public MutableByteList collectByte(ByteFunction super T> byteFunction)
{
return this.collectByte(byteFunction, new ByteArrayList(this.size));
}
@Override
public R collectByte(ByteFunction super T> byteFunction, R target)
{
for (int i = 0; i < this.size; i++)
{
target.add(byteFunction.byteValueOf(this.items[i]));
}
return target;
}
@Override
public MutableCharList collectChar(CharFunction super T> charFunction)
{
return this.collectChar(charFunction, new CharArrayList(this.size));
}
@Override
public R collectChar(CharFunction super T> charFunction, R target)
{
for (int i = 0; i < this.size; i++)
{
target.add(charFunction.charValueOf(this.items[i]));
}
return target;
}
@Override
public MutableDoubleList collectDouble(DoubleFunction super T> doubleFunction)
{
return this.collectDouble(doubleFunction, new DoubleArrayList(this.size));
}
@Override
public R collectDouble(DoubleFunction super T> doubleFunction, R target)
{
for (int i = 0; i < this.size; i++)
{
target.add(doubleFunction.doubleValueOf(this.items[i]));
}
return target;
}
@Override
public MutableFloatList collectFloat(FloatFunction super T> floatFunction)
{
return this.collectFloat(floatFunction, new FloatArrayList(this.size));
}
@Override
public R collectFloat(FloatFunction super T> floatFunction, R target)
{
for (int i = 0; i < this.size; i++)
{
target.add(floatFunction.floatValueOf(this.items[i]));
}
return target;
}
@Override
public MutableIntList collectInt(IntFunction super T> intFunction)
{
return this.collectInt(intFunction, new IntArrayList(this.size));
}
@Override
public R collectInt(IntFunction super T> intFunction, R target)
{
for (int i = 0; i < this.size; i++)
{
target.add(intFunction.intValueOf(this.items[i]));
}
return target;
}
@Override
public MutableLongList collectLong(LongFunction super T> longFunction)
{
return this.collectLong(longFunction, new LongArrayList(this.size));
}
@Override
public R collectLong(LongFunction super T> longFunction, R target)
{
for (int i = 0; i < this.size; i++)
{
target.add(longFunction.longValueOf(this.items[i]));
}
return target;
}
@Override
public MutableShortList collectShort(ShortFunction super T> shortFunction)
{
return this.collectShort(shortFunction, new ShortArrayList(this.size));
}
@Override
public R collectShort(ShortFunction super T> shortFunction, R target)
{
for (int i = 0; i < this.size; i++)
{
target.add(shortFunction.shortValueOf(this.items[i]));
}
return target;
}
@Override
public > R collect(Function super T, ? extends V> function, R target)
{
return InternalArrayIterate.collect(this.items, this.size, function, target);
}
@Override
public FastList flatCollect(Function super T, ? extends Iterable> function)
{
return this.flatCollect(function, FastList.newList(this.size()));
}
@Override
public > R flatCollect(
Function super T, ? extends Iterable> function,
R target)
{
return InternalArrayIterate.flatCollect(this.items, this.size, function, target);
}
@Override
public FastList collectWith(Function2 super T, ? super P, ? extends V> function, P parameter)
{
return this.collectWith(function, parameter, FastList.newList(this.size()));
}
@Override
public > R collectWith(
Function2 super T, ? super P, ? extends V> function,
P parameter,
R target)
{
return InternalArrayIterate.collectWith(this.items, this.size, function, parameter, target);
}
@Override
public FastList collectIf(
Predicate super T> predicate,
Function super T, ? extends V> function)
{
return this.collectIf(predicate, function, FastList.newList());
}
@Override
public > R collectIf(
Predicate super T> predicate,
Function super T, ? extends V> function,
R target)
{
return InternalArrayIterate.collectIf(this.items, this.size, predicate, function, target);
}
@Override
public T detect(Predicate super T> predicate)
{
return InternalArrayIterate.detect(this.items, this.size, predicate);
}
@Override
public T detectIfNone(Predicate super T> predicate, Function0 extends T> defaultValueBlock)
{
T result = this.detect(predicate);
return result == null ? defaultValueBlock.value() : result;
}
@Override
public int detectIndex(Predicate super T> predicate)
{
return InternalArrayIterate.detectIndex(this.items, this.size, predicate);
}
@Override
public int detectLastIndex(Predicate super T> predicate)
{
return InternalArrayIterate.detectLastIndex(this.items, this.size, predicate);
}
@Override
public T min(Comparator super T> comparator)
{
return InternalArrayIterate.min(this.items, this.size, comparator);
}
@Override
public T max(Comparator super T> comparator)
{
return InternalArrayIterate.max(this.items, this.size, comparator);
}
@Override
public T min()
{
return InternalArrayIterate.min(this.items, this.size);
}
@Override
public T max()
{
return InternalArrayIterate.max(this.items, this.size);
}
@Override
public > T minBy(Function super T, ? extends V> function)
{
return InternalArrayIterate.minBy(this.items, this.size, function);
}
@Override
public > T maxBy(Function super T, ? extends V> function)
{
return InternalArrayIterate.maxBy(this.items, this.size, function);
}
@Override
public T detectWith(Predicate2 super T, ? super P> predicate, P parameter)
{
return InternalArrayIterate.detectWith(this.items, this.size, predicate, parameter);
}
@Override
public
T detectWithIfNone(
Predicate2 super T, ? super P> predicate,
P parameter,
Function0 extends T> defaultValueBlock)
{
T result = this.detectWith(predicate, parameter);
return result == null ? defaultValueBlock.value() : result;
}
public T get(int index)
{
if (index < this.size)
{
return this.items[index];
}
throw this.newIndexOutOfBoundsException(index);
}
private IndexOutOfBoundsException newIndexOutOfBoundsException(int index)
{
return new IndexOutOfBoundsException("Index: " + index + " Size: " + this.size);
}
@Override
public boolean add(T newItem)
{
if (this.items.length == this.size)
{
this.ensureCapacityForAdd();
}
this.items[this.size++] = newItem;
return true;
}
private void ensureCapacityForAdd()
{
if (this.items == DEFAULT_SIZED_EMPTY_ARRAY)
{
this.items = (T[]) new Object[10];
}
else
{
this.transferItemsToNewArrayWithCapacity(this.sizePlusFiftyPercent(this.size));
}
}
public void add(int index, T element)
{
if (index > -1 && index < this.size)
{
this.addAtIndex(index, element);
}
else if (index == this.size)
{
this.add(element);
}
else
{
this.throwOutOfBounds(index);
}
}
private void addAtIndex(int index, T element)
{
int oldSize = this.size++;
if (this.items.length == oldSize)
{
T[] newItems = (T[]) new Object[this.sizePlusFiftyPercent(oldSize)];
if (index > 0)
{
System.arraycopy(this.items, 0, newItems, 0, index);
}
System.arraycopy(this.items, index, newItems, index + 1, oldSize - index);
this.items = newItems;
}
else
{
System.arraycopy(this.items, index, this.items, index + 1, oldSize - index);
}
this.items[index] = element;
}
private int sizePlusFiftyPercent(int oldSize)
{
int result = oldSize + (oldSize >> 1) + 1;
return result < oldSize ? MAXIMUM_ARRAY_SIZE : result;
}
public T remove(int index)
{
T previous = this.get(index);
int totalOffset = this.size - index - 1;
if (totalOffset > 0)
{
System.arraycopy(this.items, index + 1, this.items, index, totalOffset);
}
this.items[--this.size] = null;
return previous;
}
@Override
public boolean remove(Object object)
{
int index = this.indexOf(object);
if (index >= 0)
{
this.remove(index);
return true;
}
return false;
}
public boolean addAll(int index, Collection extends T> source)
{
if (index > this.size || index < 0)
{
this.throwOutOfBounds(index);
}
if (source.isEmpty())
{
return false;
}
if (source.getClass() == FastList.class)
{
this.addAllFastListAtIndex((FastList) source, index);
}
else if (source.getClass() == ArrayList.class)
{
this.addAllArrayListAtIndex((ArrayList) source, index);
}
else if (source instanceof List && source instanceof RandomAccess)
{
this.addAllRandomAccessListAtIndex((List) source, index);
}
else
{
this.addAllCollectionAtIndex(source, index);
}
return true;
}
private void addAllFastListAtIndex(FastList source, int index)
{
int sourceSize = source.size();
int newSize = this.size + sourceSize;
this.ensureCapacity(newSize);
this.shiftElementsAtIndex(index, sourceSize);
System.arraycopy(source.items, 0, this.items, index, sourceSize);
this.size = newSize;
}
private void addAllArrayListAtIndex(ArrayList source, int index)
{
int sourceSize = source.size();
int newSize = this.size + sourceSize;
this.ensureCapacity(newSize);
this.shiftElementsAtIndex(index, sourceSize);
ArrayListIterate.toArray(source, this.items, index, sourceSize);
this.size = newSize;
}
private void addAllRandomAccessListAtIndex(List source, int index)
{
int sourceSize = source.size();
int newSize = this.size + sourceSize;
this.ensureCapacity(newSize);
this.shiftElementsAtIndex(index, sourceSize);
RandomAccessListIterate.toArray(source, this.items, index, sourceSize);
this.size = newSize;
}
private void addAllCollectionAtIndex(Collection extends T> source, int index)
{
Object[] newItems = source.toArray();
int sourceSize = newItems.length;
int newSize = this.size + sourceSize;
this.ensureCapacity(newSize);
this.shiftElementsAtIndex(index, sourceSize);
this.size = newSize;
System.arraycopy(newItems, 0, this.items, index, sourceSize);
}
private void shiftElementsAtIndex(int index, int sourceSize)
{
int numberToMove = this.size - index;
if (numberToMove > 0)
{
System.arraycopy(this.items, index, this.items, index + sourceSize, numberToMove);
}
}
public int size()
{
return this.size;
}
@Override
public int count(Predicate super T> predicate)
{
return InternalArrayIterate.count(this.items, this.size, predicate);
}
@Override
public int countWith(Predicate2 super T, ? super P> predicate, P parameter)
{
return InternalArrayIterate.countWith(this.items, this.size, predicate, parameter);
}
@Override
public boolean corresponds(OrderedIterable other, Predicate2 super T, ? super S> predicate)
{
return InternalArrayIterate.corresponds(this.items, this.size, other, predicate);
}
@Override
public boolean anySatisfy(Predicate super T> predicate)
{
return InternalArrayIterate.anySatisfy(this.items, this.size, predicate);
}
@Override
public
boolean anySatisfyWith(Predicate2 super T, ? super P> predicate, P parameter)
{
return InternalArrayIterate.anySatisfyWith(this.items, this.size, predicate, parameter);
}
@Override
public boolean allSatisfy(Predicate super T> predicate)
{
return InternalArrayIterate.allSatisfy(this.items, this.size, predicate);
}
@Override
public
boolean allSatisfyWith(Predicate2 super T, ? super P> predicate, P parameter)
{
return InternalArrayIterate.allSatisfyWith(this.items, this.size, predicate, parameter);
}
@Override
public boolean noneSatisfy(Predicate super T> predicate)
{
return InternalArrayIterate.noneSatisfy(this.items, this.size, predicate);
}
@Override
public
boolean noneSatisfyWith(Predicate2 super T, ? super P> predicate, P parameter)
{
return InternalArrayIterate.noneSatisfyWith(this.items, this.size, predicate, parameter);
}
@Override
public IV injectInto(IV injectedValue, Function2 super IV, ? super T, ? extends IV> function)
{
IV result = injectedValue;
for (int i = 0; i < this.size; i++)
{
result = function.value(result, this.items[i]);
}
return result;
}
@Override
public int injectInto(int injectedValue, IntObjectToIntFunction super T> function)
{
int result = injectedValue;
for (int i = 0; i < this.size; i++)
{
result = function.intValueOf(result, this.items[i]);
}
return result;
}
@Override
public long injectInto(long injectedValue, LongObjectToLongFunction super T> function)
{
long result = injectedValue;
for (int i = 0; i < this.size; i++)
{
result = function.longValueOf(result, this.items[i]);
}
return result;
}
@Override
public double injectInto(double injectedValue, DoubleObjectToDoubleFunction super T> function)
{
double result = injectedValue;
for (int i = 0; i < this.size; i++)
{
result = function.doubleValueOf(result, this.items[i]);
}
return result;
}
@Override
public float injectInto(float injectedValue, FloatObjectToFloatFunction super T> function)
{
float result = injectedValue;
for (int i = 0; i < this.size; i++)
{
result = function.floatValueOf(result, this.items[i]);
}
return result;
}
@Override
public MutableList distinct()
{
return InternalArrayIterate.distinct(this.items, this.size);
}
@Override
public MutableList distinct(HashingStrategy super T> hashingStrategy)
{
return InternalArrayIterate.distinct(this.items, this.size, hashingStrategy);
}
@Override
public long sumOfInt(IntFunction super T> function)
{
return InternalArrayIterate.sumOfInt(this.items, this.size, function);
}
@Override
public long sumOfLong(LongFunction super T> function)
{
return InternalArrayIterate.sumOfLong(this.items, this.size, function);
}
@Override
public double sumOfFloat(FloatFunction super T> function)
{
return InternalArrayIterate.sumOfFloat(this.items, this.size, function);
}
@Override
public double sumOfDouble(DoubleFunction super T> function)
{
return InternalArrayIterate.sumOfDouble(this.items, this.size, function);
}
@Override
public ObjectLongMap sumByInt(Function groupBy, IntFunction super T> function)
{
return InternalArrayIterate.sumByInt(this.items, this.size, groupBy, function);
}
@Override
public ObjectLongMap sumByLong(Function groupBy, LongFunction super T> function)
{
return InternalArrayIterate.sumByLong(this.items, this.size, groupBy, function);
}
@Override
public ObjectDoubleMap sumByFloat(Function groupBy, FloatFunction super T> function)
{
return InternalArrayIterate.sumByFloat(this.items, this.size, groupBy, function);
}
@Override
public ObjectDoubleMap sumByDouble(Function groupBy, DoubleFunction super T> function)
{
return InternalArrayIterate.sumByDouble(this.items, this.size, groupBy, function);
}
@Override
public IV injectIntoWith(
IV injectValue,
Function3 super IV, ? super T, ? super P, ? extends IV> function,
P parameter)
{
IV result = injectValue;
for (int i = 0; i < this.size; i++)
{
result = function.value(result, this.items[i], parameter);
}
return result;
}
@Override
public FastList toList()
{
return FastList.newList(this);
}
@Override
public FastList toSortedList()
{
return this.toSortedList(Comparators.naturalOrder());
}
@Override
public FastList toSortedList(Comparator super T> comparator)
{
return FastList.newList(this).sortThis(comparator);
}
@Override
public MutableList takeWhile(Predicate super T> predicate)
{
int endIndex = this.detectNotIndex(predicate);
T[] result = (T[]) new Object[endIndex];
System.arraycopy(this.items, 0, result, 0, endIndex);
return FastList.newListWith(result);
}
@Override
public MutableList dropWhile(Predicate super T> predicate)
{
int startIndex = this.detectNotIndex(predicate);
int resultSize = this.size() - startIndex;
T[] result = (T[]) new Object[resultSize];
System.arraycopy(this.items, startIndex, result, 0, resultSize);
return FastList.newListWith(result);
}
@Override
public PartitionMutableList partitionWhile(Predicate super T> predicate)
{
PartitionMutableList result = new PartitionFastList();
FastList selected = (FastList) result.getSelected();
FastList rejected = (FastList) result.getRejected();
int partitionIndex = this.detectNotIndex(predicate);
int rejectedSize = this.size() - partitionIndex;
selected.withArrayCopy(this.items, 0, partitionIndex);
rejected.withArrayCopy(this.items, partitionIndex, rejectedSize);
return result;
}
private int detectNotIndex(Predicate super T> predicate)
{
for (int index = 0; index < this.size; index++)
{
if (!predicate.accept(this.items[index]))
{
return index;
}
}
return this.size;
}
@Override
public boolean equals(Object that)
{
if (that == this)
{
return true;
}
if (!(that instanceof List))
{
return false;
}
if (that instanceof FastList)
{
return this.fastListEquals((FastList>) that);
}
return InternalArrayIterate.arrayEqualsList(this.items, this.size, (List>) that);
}
public boolean fastListEquals(FastList> that)
{
if (this.size != that.size)
{
return false;
}
for (int i = 0; i < this.size; i++)
{
if (!Comparators.nullSafeEquals(this.items[i], that.items[i]))
{
return false;
}
}
return true;
}
@Override
public int hashCode()
{
int hashCode = 1;
for (int i = 0; i < this.size; i++)
{
T item = this.items[i];
hashCode = 31 * hashCode + (item == null ? 0 : item.hashCode());
}
return hashCode;
}
public void writeExternal(ObjectOutput out) throws IOException
{
out.writeInt(this.size());
for (int i = 0; i < this.size; i++)
{
out.writeObject(this.items[i]);
}
}
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
{
this.size = in.readInt();
this.items = (T[]) new Object[this.size];
for (int i = 0; i < this.size; i++)
{
this.items[i] = (T) in.readObject();
}
}
}