package org.eclipse.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.DoubleSummaryStatistics;
import java.util.IntSummaryStatistics;
import java.util.List;
import java.util.LongSummaryStatistics;
import java.util.Optional;
import java.util.RandomAccess;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
import java.util.function.Supplier;
import java.util.stream.Collector;
import org.eclipse.collections.api.block.HashingStrategy;
import org.eclipse.collections.api.block.function.Function;
import org.eclipse.collections.api.block.function.Function0;
import org.eclipse.collections.api.block.function.Function2;
import org.eclipse.collections.api.block.function.Function3;
import org.eclipse.collections.api.block.function.primitive.BooleanFunction;
import org.eclipse.collections.api.block.function.primitive.ByteFunction;
import org.eclipse.collections.api.block.function.primitive.CharFunction;
import org.eclipse.collections.api.block.function.primitive.DoubleFunction;
import org.eclipse.collections.api.block.function.primitive.DoubleObjectToDoubleFunction;
import org.eclipse.collections.api.block.function.primitive.FloatFunction;
import org.eclipse.collections.api.block.function.primitive.FloatObjectToFloatFunction;
import org.eclipse.collections.api.block.function.primitive.IntFunction;
import org.eclipse.collections.api.block.function.primitive.IntObjectToIntFunction;
import org.eclipse.collections.api.block.function.primitive.LongFunction;
import org.eclipse.collections.api.block.function.primitive.LongObjectToLongFunction;
import org.eclipse.collections.api.block.function.primitive.ObjectIntToObjectFunction;
import org.eclipse.collections.api.block.function.primitive.ShortFunction;
import org.eclipse.collections.api.block.predicate.Predicate;
import org.eclipse.collections.api.block.predicate.Predicate2;
import org.eclipse.collections.api.block.procedure.Procedure;
import org.eclipse.collections.api.block.procedure.Procedure2;
import org.eclipse.collections.api.block.procedure.primitive.ObjectIntProcedure;
import org.eclipse.collections.api.collection.primitive.MutableBooleanCollection;
import org.eclipse.collections.api.collection.primitive.MutableByteCollection;
import org.eclipse.collections.api.collection.primitive.MutableCharCollection;
import org.eclipse.collections.api.collection.primitive.MutableDoubleCollection;
import org.eclipse.collections.api.collection.primitive.MutableFloatCollection;
import org.eclipse.collections.api.collection.primitive.MutableIntCollection;
import org.eclipse.collections.api.collection.primitive.MutableLongCollection;
import org.eclipse.collections.api.collection.primitive.MutableShortCollection;
import org.eclipse.collections.api.list.MutableList;
import org.eclipse.collections.api.list.primitive.MutableBooleanList;
import org.eclipse.collections.api.list.primitive.MutableByteList;
import org.eclipse.collections.api.list.primitive.MutableCharList;
import org.eclipse.collections.api.list.primitive.MutableDoubleList;
import org.eclipse.collections.api.list.primitive.MutableFloatList;
import org.eclipse.collections.api.list.primitive.MutableIntList;
import org.eclipse.collections.api.list.primitive.MutableLongList;
import org.eclipse.collections.api.list.primitive.MutableShortList;
import org.eclipse.collections.api.map.MutableMap;
import org.eclipse.collections.api.map.primitive.MutableObjectDoubleMap;
import org.eclipse.collections.api.map.primitive.MutableObjectLongMap;
import org.eclipse.collections.api.multimap.MutableMultimap;
import org.eclipse.collections.api.ordered.OrderedIterable;
import org.eclipse.collections.api.partition.list.PartitionMutableList;
import org.eclipse.collections.api.tuple.Twin;
import org.eclipse.collections.impl.block.factory.Comparators;
import org.eclipse.collections.impl.block.factory.Predicates2;
import org.eclipse.collections.impl.block.factory.Procedures2;
import org.eclipse.collections.impl.list.mutable.primitive.BooleanArrayList;
import org.eclipse.collections.impl.list.mutable.primitive.ByteArrayList;
import org.eclipse.collections.impl.list.mutable.primitive.CharArrayList;
import org.eclipse.collections.impl.list.mutable.primitive.DoubleArrayList;
import org.eclipse.collections.impl.list.mutable.primitive.FloatArrayList;
import org.eclipse.collections.impl.list.mutable.primitive.IntArrayList;
import org.eclipse.collections.impl.list.mutable.primitive.LongArrayList;
import org.eclipse.collections.impl.list.mutable.primitive.ShortArrayList;
import org.eclipse.collections.impl.map.mutable.UnifiedMap;
import org.eclipse.collections.impl.multimap.list.FastListMultimap;
import org.eclipse.collections.impl.parallel.BatchIterable;
import org.eclipse.collections.impl.partition.list.PartitionFastList;
import org.eclipse.collections.impl.utility.ArrayIterate;
import org.eclipse.collections.impl.utility.ArrayListIterate;
import org.eclipse.collections.impl.utility.Iterate;
import org.eclipse.collections.impl.utility.ListIterate;
import org.eclipse.collections.impl.utility.internal.InternalArrayIterate;
import org.eclipse.collections.impl.utility.internal.RandomAccessListIterate;
public class FastList<T>
extends AbstractMutableList<T>
implements Externalizable, RandomAccess, BatchIterable<T>
{
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 <E> FastList<E> newList()
{
return new FastList<>();
}
public static <E> FastList<E> wrapCopy(E... array)
{
E[] newArray = (E[]) new Object[array.length];
System.arraycopy(array, 0, newArray, 0, array.length);
return new FastList<>(newArray);
}
public static <E> FastList<E> newList(int initialCapacity)
{
return new FastList<>(initialCapacity);
}
public static <E> FastList<E> newList(Iterable<? extends E> source)
{
return FastList.newListWith((E[]) Iterate.toArray(source));
}
public static <E> FastList<E> newListWith(E... elements)
{
return new FastList<>(elements);
}
public static <E> FastList<E> newWithNValues(int size, Function0<E> factory)
{
FastList<E> newFastList = FastList.newList(size);
for (int i = 0; i < size; i++)
{
newFastList.add(factory.value());
}
return newFastList;
}
@Override
public FastList<T> clone()
{
FastList<T> result = (FastList<T>) super.clone();
if (this.items.length > 0)
{
result.items = this.items.clone();
}
return result;
}
@Override
public void clear()
{
Arrays.fill(this.items, 0, this.size, 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);
}
@Override
public void batchForEach(Procedure<? super T> procedure, int sectionIndex, int sectionCount)
{
InternalArrayIterate.batchForEach(procedure, this.items, this.size, sectionIndex, sectionCount);
}
@Override
public int getBatchCount(int batchSize)
{
return Math.max(1, this.size() / batchSize);
}
public <E> E[] toArray(E[] array, int sourceFromIndex, int sourceToIndex, int destinationIndex)
{
System.arraycopy(this.items, sourceFromIndex, array, destinationIndex, sourceToIndex - sourceFromIndex + 1);
return array;
}
public <E> E[] toArray(int sourceFromIndex, int sourceToIndex)
{
return this.toArray((E[]) new Object[sourceToIndex - sourceFromIndex + 1], sourceFromIndex, sourceToIndex, 0);
}
@Override
public FastList<T> sortThis(Comparator<? super T> comparator)
{
Arrays.sort(this.items, 0, this.size, comparator);
return this;
}
@Override
public FastList<T> sortThis()
{
Arrays.sort(this.items, 0, this.size);
return this;
}
@Override
public FastList<T> 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<T>) source);
}
else if (source.getClass() == ArrayList.class)
{
this.addAllArrayList((ArrayList<T>) source);
}
else if (source instanceof List && source instanceof RandomAccess)
{
this.addAllRandomAccessList((List<T>) source);
}
else
{
this.addAllCollection(source);
}
return true;
}
private void addAllFastList(FastList<T> source)
{
int newSize = this.ensureCapacityForAddAll(source);
System.arraycopy(source.items, 0, this.items, this.size, source.size());
this.size = newSize;
}
private void addAllArrayList(ArrayList<T> source)
{
int newSize = this.ensureCapacityForAddAll(source);
ArrayListIterate.toArray(source, this.items, this.size, source.size());
this.size = newSize;
}
private void addAllRandomAccessList(List<T> source)
{
int newSize = this.ensureCapacityForAddAll(source);
RandomAccessListIterate.toArray(source, this.items, this.size, source.size());
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> 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<T> 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);
}
@Override
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);
}
@Override
public Spliterator<T> spliterator()
{
return Spliterators.spliterator(this.items, 0, this.size, Spliterator.ORDERED);
}
public void trimToSize()
{
if (this.size < this.items.length)
{
this.transferItemsToNewArrayWithCapacity(this.size);
}
}
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;
}
private void ensureCapacityForAdd()
{
if (this.items == DEFAULT_SIZED_EMPTY_ARRAY)
{
this.items = (T[]) new Object[10];
}
else
{
this.transferItemsToNewArrayWithCapacity(this.sizePlusFiftyPercent(this.size));
}
}
private int ensureCapacityForAddAll(Collection<T> source)
{
int sourceSize = source.size();
int newSize = this.size + sourceSize;
this.ensureCapacity(newSize);
return newSize;
}
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<T> with(T element1, T element2)
{
this.add(element1);
this.add(element2);
return this;
}
public FastList<T> with(T element1, T element2, T element3)
{
this.add(element1);
this.add(element2);
this.add(element3);
return this;
}
public FastList<T> with(T... elements)
{
return this.withArrayCopy(elements, 0, elements.length);
}
public FastList<T> 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 <V> FastListMultimap<V, T> groupBy(Function<? super T, ? extends V> function)
{
return this.groupBy(function, FastListMultimap.newMultimap());
}
@Override
public <V, R extends MutableMultimap<V, T>> R groupBy(Function<? super T, ? extends V> function, R target)
{
return InternalArrayIterate.groupBy(this.items, this.size, function, target);
}
@Override
public <V> FastListMultimap<V, T> groupByEach(Function<? super T, ? extends Iterable<V>> function)
{
return this.groupByEach(function, FastListMultimap.newMultimap());
}
@Override
public <V, R extends MutableMultimap<V, T>> R groupByEach(
Function<? super T, ? extends Iterable<V>> function,
R target)
{
return InternalArrayIterate.groupByEach(this.items, this.size, function, target);
}
@Override
public <K> MutableMap<K, T> groupByUniqueKey(Function<? super T, ? extends K> function)
{
return this.groupByUniqueKey(function, UnifiedMap.newMap(this.size()));
}
@Override
public <K, R extends MutableMap<K, T>> 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<T> take(int count)
{
return RandomAccessListIterate.take(this, count);
}
@Override
public MutableList<T> drop(int count)
{
return RandomAccessListIterate.drop(this, count);
}
@Override
public PartitionFastList<T> partition(Predicate<? super T> predicate)
{
return InternalArrayIterate.partition(this.items, this.size, predicate);
}
@Override
public <P> PartitionFastList<T> 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 <P> 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<T> select(Predicate<? super T> predicate)
{
return this.select(predicate, FastList.newList());
}
@Override
public <R extends Collection<T>> R select(Predicate<? super T> predicate, R target)
{
return InternalArrayIterate.select(this.items, this.size, predicate, target);
}
@Override
public <P> FastList<T> selectWith(Predicate2<? super T, ? super P> predicate, P parameter)
{
return this.selectWith(predicate, parameter, FastList.newList());
}
@Override
public <P, R extends Collection<T>> 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<T> reject(Predicate<? super T> predicate)
{
return this.reject(predicate, FastList.newList());
}
@Override
public <R extends Collection<T>> R reject(Predicate<? super T> predicate, R target)
{
return InternalArrayIterate.reject(this.items, this.size, predicate, target);
}
@Override
public <P> FastList<T> rejectWith(Predicate2<? super T, ? super P> predicate, P parameter)
{
return this.rejectWith(predicate, parameter, FastList.newList());
}
@Override
public <P, R extends Collection<T>> R rejectWith(
Predicate2<? super T, ? super P> predicate,
P parameter,
R target)
{
return InternalArrayIterate.rejectWith(this.items, this.size, predicate, parameter, target);
}
@Override
public <P> Twin<MutableList<T>> selectAndRejectWith(
Predicate2<? super T, ? super P> predicate,
P parameter)
{
return InternalArrayIterate.selectAndRejectWith(this.items, this.size, predicate, parameter);
}
@Override
public <S> FastList<S> selectInstancesOf(Class<S> 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))
{
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 <P> 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))
{
if (currentFilledIndex != i)
{
this.items[currentFilledIndex] = item;
}
currentFilledIndex++;
}
}
boolean changed = currentFilledIndex < this.size;
this.wipeAndResetTheEnd(currentFilledIndex);
return changed;
}
@Override
public <V> FastList<V> 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 extends MutableBooleanCollection> 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 extends MutableByteCollection> 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 extends MutableCharCollection> 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 extends MutableDoubleCollection> 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 extends MutableFloatCollection> 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 extends MutableIntCollection> 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 extends MutableLongCollection> 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 extends MutableShortCollection> 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 <V, R extends Collection<V>> R collect(Function<? super T, ? extends V> function, R target)
{
return InternalArrayIterate.collect(this.items, this.size, function, target);
}
@Override
public <V> MutableList<V> collectWithIndex(ObjectIntToObjectFunction<? super T, ? extends V> function)
{
return this.collectWithIndex(function, FastList.newList(this.size));
}
@Override
public <V, R extends Collection<V>> R collectWithIndex(ObjectIntToObjectFunction<? super T, ? extends V> function, R target)
{
return InternalArrayIterate.collectWithIndex(this.items, this.size, function, target);
}
@Override
public <V> FastList<V> flatCollect(Function<? super T, ? extends Iterable<V>> function)
{
return this.flatCollect(function, FastList.newList(this.size()));
}
@Override
public <V, R extends Collection<V>> R flatCollect(
Function<? super T, ? extends Iterable<V>> function,
R target)
{
return InternalArrayIterate.flatCollect(this.items, this.size, function, target);
}
@Override
public <P, V> FastList<V> collectWith(Function2<? super T, ? super P, ? extends V> function, P parameter)
{
return this.collectWith(function, parameter, FastList.newList(this.size()));
}
@Override
public <P, V, R extends Collection<V>> 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 <V> FastList<V> collectIf(
Predicate<? super T> predicate,
Function<? super T, ? extends V> function)
{
return this.collectIf(predicate, function, FastList.newList());
}
@Override
public <V, R extends Collection<V>> 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 <P> T detectWith(Predicate2<? super T, ? super P> predicate, P parameter)
{
return InternalArrayIterate.detectWith(this.items, this.size, predicate, parameter);
}
@Override
public Optional<T> detectOptional(Predicate<? super T> predicate)
{
return InternalArrayIterate.detectOptional(this.items, this.size, predicate);
}
@Override
public <P> Optional<T> detectWithOptional(Predicate2<? super T, ? super P> predicate, P parameter)
{
return InternalArrayIterate.detectWithOptional(this.items, this.size, predicate, parameter);
}
@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 <V extends Comparable<? super V>> T minBy(Function<? super T, ? extends V> function)
{
return InternalArrayIterate.minBy(this.items, this.size, function);
}
@Override
public <V extends Comparable<? super V>> T maxBy(Function<? super T, ? extends V> function)
{
return InternalArrayIterate.maxBy(this.items, this.size, function);
}
@Override
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;
}
@Override
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;
}
@Override
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;
}
@Override
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<T>) source, index);
}
else if (source.getClass() == ArrayList.class)
{
this.addAllArrayListAtIndex((ArrayList<T>) source, index);
}
else if (source instanceof List && source instanceof RandomAccess)
{
this.addAllRandomAccessListAtIndex((List<T>) source, index);
}
else
{
this.addAllCollectionAtIndex(source, index);
}
return true;
}
private void addAllFastListAtIndex(FastList<T> 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<T> 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<T> 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);
}
}
@Override
public int size()
{
return this.size;
}
@Override
public int count(Predicate<? super T> predicate)
{
return InternalArrayIterate.count(this.items, this.size, predicate);
}
@Override
public <P> int countWith(Predicate2<? super T, ? super P> predicate, P parameter)
{
return InternalArrayIterate.countWith(this.items, this.size, predicate, parameter);
}
@Override
public <S> boolean corresponds(OrderedIterable<S> 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 <P> 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 <P> 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 <P> boolean noneSatisfyWith(Predicate2<? super T, ? super P> predicate, P parameter)
{
return InternalArrayIterate.noneSatisfyWith(this.items, this.size, predicate, parameter);
}
@Override
public <IV> 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<T> distinct()
{
return InternalArrayIterate.distinct(this.items, this.size);
}
@Override
public MutableList<T> distinct(HashingStrategy<? super T> hashingStrategy)
{
return InternalArrayIterate.distinct(this.items, this.size, hashingStrategy);
}
@Override
public IntSummaryStatistics summarizeInt(IntFunction<? super T> function)
{
return InternalArrayIterate.summarizeInt(this.items, this.size, function);
}
@Override
public DoubleSummaryStatistics summarizeFloat(FloatFunction<? super T> function)
{
return InternalArrayIterate.summarizeFloat(this.items, this.size, function);
}
@Override
public LongSummaryStatistics summarizeLong(LongFunction<? super T> function)
{
return InternalArrayIterate.summarizeLong(this.items, this.size, function);
}
@Override
public DoubleSummaryStatistics summarizeDouble(DoubleFunction<? super T> function)
{
return InternalArrayIterate.summarizeDouble(this.items, this.size, function);
}
@Override
public Optional<T> reduce(BinaryOperator<T> accumulator)
{
return InternalArrayIterate.reduce(this.items, this.size, accumulator);
}
@Override
public <R, A> R reduceInPlace(Collector<? super T, A, R> collector)
{
return InternalArrayIterate.reduceInPlace(this.items, this.size, collector);
}
@Override
public <R> R reduceInPlace(Supplier<R> supplier, BiConsumer<R, ? super T> accumulator)
{
return InternalArrayIterate.reduceInPlace(this.items, this.size, supplier, accumulator);
}
@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 <V> MutableObjectLongMap<V> sumByInt(Function<? super T, ? extends V> groupBy, IntFunction<? super T> function)
{
return InternalArrayIterate.sumByInt(this.items, this.size, groupBy, function);
}
@Override
public <V> MutableObjectLongMap<V> sumByLong(Function<? super T, ? extends V> groupBy, LongFunction<? super T> function)
{
return InternalArrayIterate.sumByLong(this.items, this.size, groupBy, function);
}
@Override
public <V> MutableObjectDoubleMap<V> sumByFloat(Function<? super T, ? extends V> groupBy, FloatFunction<? super T> function)
{
return InternalArrayIterate.sumByFloat(this.items, this.size, groupBy, function);
}
@Override
public <V> MutableObjectDoubleMap<V> sumByDouble(Function<? super T, ? extends V> groupBy, DoubleFunction<? super T> function)
{
return InternalArrayIterate.sumByDouble(this.items, this.size, groupBy, function);
}
@Override
public <IV, P> 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<T> toList()
{
return FastList.newList(this);
}
@Override
public FastList<T> toSortedList()
{
return this.toSortedList(Comparators.naturalOrder());
}
@Override
public FastList<T> toSortedList(Comparator<? super T> comparator)
{
return FastList.newList(this).sortThis(comparator);
}
@Override
public MutableList<T> 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<T> 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<T> partitionWhile(Predicate<? super T> predicate)
{
PartitionMutableList<T> result = new PartitionFastList<>();
FastList<T> selected = (FastList<T>) result.getSelected();
FastList<T> rejected = (FastList<T>) 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;
}
@Override
public void writeExternal(ObjectOutput out) throws IOException
{
out.writeInt(this.size());
for (int i = 0; i < this.size; i++)
{
out.writeObject(this.items[i]);
}
}
@Override
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();
}
}
}