org.eclipse.collections.impl.utility.internal.InternalArrayIterate Maven / Gradle / Ivy
Show all versions of eclipse-collections Show documentation
/*
* Copyright (c) 2022 Goldman Sachs and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v. 1.0 which accompany this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*/
package org.eclipse.collections.impl.utility.internal;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.DoubleSummaryStatistics;
import java.util.IntSummaryStatistics;
import java.util.Iterator;
import java.util.List;
import java.util.LongSummaryStatistics;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Optional;
import java.util.RandomAccess;
import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
import java.util.function.Supplier;
import java.util.function.UnaryOperator;
import java.util.stream.Collector;
import org.eclipse.collections.api.RichIterable;
import org.eclipse.collections.api.block.HashingStrategy;
import org.eclipse.collections.api.block.function.Function;
import org.eclipse.collections.api.block.function.Function2;
import org.eclipse.collections.api.block.function.primitive.DoubleFunction;
import org.eclipse.collections.api.block.function.primitive.FloatFunction;
import org.eclipse.collections.api.block.function.primitive.IntFunction;
import org.eclipse.collections.api.block.function.primitive.LongFunction;
import org.eclipse.collections.api.block.function.primitive.ObjectIntToObjectFunction;
import org.eclipse.collections.api.block.predicate.Predicate;
import org.eclipse.collections.api.block.predicate.Predicate2;
import org.eclipse.collections.api.block.predicate.primitive.ObjectIntPredicate;
import org.eclipse.collections.api.block.procedure.Procedure;
import org.eclipse.collections.api.block.procedure.primitive.ObjectIntProcedure;
import org.eclipse.collections.api.factory.Lists;
import org.eclipse.collections.api.factory.Sets;
import org.eclipse.collections.api.factory.primitive.ObjectDoubleMaps;
import org.eclipse.collections.api.factory.primitive.ObjectLongMaps;
import org.eclipse.collections.api.list.ListIterable;
import org.eclipse.collections.api.list.MutableList;
import org.eclipse.collections.api.map.MutableMapIterable;
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.set.MutableSet;
import org.eclipse.collections.api.tuple.Twin;
import org.eclipse.collections.impl.block.procedure.CountProcedure;
import org.eclipse.collections.impl.block.procedure.FastListCollectIfProcedure;
import org.eclipse.collections.impl.block.procedure.FastListCollectProcedure;
import org.eclipse.collections.impl.block.procedure.FastListRejectProcedure;
import org.eclipse.collections.impl.block.procedure.FastListSelectProcedure;
import org.eclipse.collections.impl.block.procedure.MultimapPutProcedure;
import org.eclipse.collections.impl.list.mutable.FastList;
import org.eclipse.collections.impl.partition.list.PartitionFastList;
import org.eclipse.collections.impl.set.strategy.mutable.UnifiedSetWithHashingStrategy;
import org.eclipse.collections.impl.tuple.Tuples;
import org.eclipse.collections.impl.utility.ArrayIterate;
import org.eclipse.collections.impl.utility.Iterate;
@SuppressWarnings("TypeMayBeWeakened")
public final class InternalArrayIterate
{
private InternalArrayIterate()
{
throw new AssertionError("Suppress default constructor for noninstantiability");
}
public static boolean arrayEqualsList(T[] array, int size, List> list)
{
if (size != list.size())
{
return false;
}
if (list instanceof RandomAccess)
{
return InternalArrayIterate.randomAccessListEquals(array, size, list);
}
return InternalArrayIterate.nonRandomAccessListEquals(array, size, list);
}
private static boolean randomAccessListEquals(T[] array, int size, List> list)
{
for (int i = 0; i < size; i++)
{
if (!Objects.equals(array[i], list.get(i)))
{
return false;
}
}
return true;
}
private static boolean nonRandomAccessListEquals(T[] array, int size, List> list)
{
Iterator> iterator = list.iterator();
for (int i = 0; i < size; i++)
{
if (!iterator.hasNext())
{
return false;
}
if (!Objects.equals(array[i], iterator.next()))
{
return false;
}
}
return !iterator.hasNext();
}
public static void forEachWithoutChecks(T[] objectArray, int from, int to, Procedure super T> procedure)
{
if (from <= to)
{
for (int i = from; i <= to; i++)
{
procedure.value(objectArray[i]);
}
}
else
{
for (int i = from; i >= to; i--)
{
procedure.value(objectArray[i]);
}
}
}
public static void forEachWithIndexWithoutChecks(T[] objectArray, int from, int to, ObjectIntProcedure super T> objectIntProcedure)
{
if (from <= to)
{
for (int i = from; i <= to; i++)
{
objectIntProcedure.value(objectArray[i], i);
}
}
else
{
for (int i = from; i >= to; i--)
{
objectIntProcedure.value(objectArray[i], i);
}
}
}
public static void batchForEach(Procedure super T> procedure, T[] array, int size, int sectionIndex, int sectionCount)
{
int sectionSize = size / sectionCount;
int start = sectionSize * sectionIndex;
int end = sectionIndex == sectionCount - 1 ? size : start + sectionSize;
if (procedure instanceof FastListSelectProcedure)
{
InternalArrayIterate.batchFastListSelect(array, start, end, (FastListSelectProcedure) procedure);
}
else if (procedure instanceof FastListCollectProcedure)
{
InternalArrayIterate.batchFastListCollect(array, start, end, (FastListCollectProcedure) procedure);
}
else if (procedure instanceof FastListCollectIfProcedure)
{
InternalArrayIterate.batchFastListCollectIf(array, start, end, (FastListCollectIfProcedure) procedure);
}
else if (procedure instanceof CountProcedure)
{
InternalArrayIterate.batchCount(array, start, end, (CountProcedure) procedure);
}
else if (procedure instanceof FastListRejectProcedure)
{
InternalArrayIterate.batchReject(array, start, end, (FastListRejectProcedure) procedure);
}
else if (procedure instanceof MultimapPutProcedure)
{
InternalArrayIterate.batchGroupBy(array, start, end, (MultimapPutProcedure, T>) procedure);
}
else
{
for (int i = start; i < end; i++)
{
procedure.value(array[i]);
}
}
}
/**
* Implemented to avoid megamorphic call on castProcedure.
*/
private static void batchGroupBy(T[] array, int start, int end, MultimapPutProcedure, T> castProcedure)
{
for (int i = start; i < end; i++)
{
castProcedure.value(array[i]);
}
}
/**
* Implemented to avoid megamorphic call on castProcedure.
*/
private static void batchReject(T[] array, int start, int end, FastListRejectProcedure castProcedure)
{
for (int i = start; i < end; i++)
{
castProcedure.value(array[i]);
}
}
/**
* Implemented to avoid megamorphic call on castProcedure.
*/
private static void batchCount(T[] array, int start, int end, CountProcedure castProcedure)
{
for (int i = start; i < end; i++)
{
castProcedure.value(array[i]);
}
}
/**
* Implemented to avoid megamorphic call on castProcedure.
*/
private static void batchFastListCollectIf(T[] array, int start, int end, FastListCollectIfProcedure castProcedure)
{
for (int i = start; i < end; i++)
{
castProcedure.value(array[i]);
}
}
/**
* Implemented to avoid megamorphic call on castProcedure.
*/
private static void batchFastListCollect(T[] array, int start, int end, FastListCollectProcedure castProcedure)
{
for (int i = start; i < end; i++)
{
castProcedure.value(array[i]);
}
}
/**
* Implemented to avoid megamorphic call on castProcedure.
*/
private static void batchFastListSelect(T[] array, int start, int end, FastListSelectProcedure castProcedure)
{
for (int i = start; i < end; i++)
{
castProcedure.value(array[i]);
}
}
public static > R groupBy(T[] array, int size, Function super T, ? extends V> function, R target)
{
for (int i = 0; i < size; i++)
{
T item = array[i];
target.put(function.valueOf(item), item);
}
return target;
}
public static > R groupByEach(
T[] array,
int size,
Function super T, ? extends Iterable> function,
R target)
{
for (int i = 0; i < size; i++)
{
T item = array[i];
Iterable iterable = function.valueOf(item);
for (V key : iterable)
{
target.put(key, item);
}
}
return target;
}
public static > R groupByUniqueKey(
T[] array,
int size,
Function super T, ? extends K> function,
R target)
{
for (int i = 0; i < size; i++)
{
T value = array[i];
K key = function.valueOf(value);
if (target.put(key, value) != null)
{
throw new IllegalStateException("Key " + key + " already exists in map!");
}
}
return target;
}
public static PartitionFastList partition(T[] array, int size, Predicate super T> predicate)
{
PartitionFastList partitionFastList = new PartitionFastList<>();
for (int i = 0; i < size; i++)
{
T each = array[i];
MutableList bucket = predicate.accept(each)
? partitionFastList.getSelected()
: partitionFastList.getRejected();
bucket.add(each);
}
return partitionFastList;
}
public static PartitionFastList partitionWith(T[] array, int size, Predicate2 super T, ? super P> predicate, P parameter)
{
PartitionFastList partitionFastList = new PartitionFastList<>();
for (int i = 0; i < size; i++)
{
T each = array[i];
MutableList bucket = predicate.accept(each, parameter)
? partitionFastList.getSelected()
: partitionFastList.getRejected();
bucket.add(each);
}
return partitionFastList;
}
/**
* @see Iterate#selectAndRejectWith(Iterable, Predicate2, Object)
* @deprecated since 6.0 use {@link RichIterable#partitionWith(Predicate2, Object)} instead.
*/
@Deprecated
public static Twin> selectAndRejectWith(T[] objectArray, int size, Predicate2 super T, ? super P> predicate, P parameter)
{
MutableList positiveResult = Lists.mutable.empty();
MutableList negativeResult = Lists.mutable.empty();
for (int i = 0; i < size; i++)
{
T each = objectArray[i];
(predicate.accept(each, parameter) ? positiveResult : negativeResult).add(each);
}
return Tuples.twin(positiveResult, negativeResult);
}
public static int indexOf(Object[] array, int size, Object object)
{
for (int i = 0; i < size; i++)
{
if (Objects.equals(array[i], object))
{
return i;
}
}
return -1;
}
public static int lastIndexOf(Object[] array, int size, Object object)
{
for (int i = size - 1; i >= 0; i--)
{
if (Objects.equals(array[i], object))
{
return i;
}
}
return -1;
}
public static > R select(T[] array, int size, Predicate super T> predicate, R target)
{
for (int i = 0; i < size; i++)
{
T item = array[i];
if (predicate.accept(item))
{
target.add(item);
}
}
return target;
}
public static > R selectWith(
T[] array,
int size,
Predicate2 super T, ? super P> predicate,
P parameter,
R targetCollection)
{
for (int i = 0; i < size; i++)
{
T item = array[i];
if (predicate.accept(item, parameter))
{
targetCollection.add(item);
}
}
return targetCollection;
}
public static > R reject(T[] array, int size, Predicate super T> predicate, R target)
{
for (int i = 0; i < size; i++)
{
T item = array[i];
if (!predicate.accept(item))
{
target.add(item);
}
}
return target;
}
public static > R rejectWith(
T[] array,
int size,
Predicate2 super T, ? super P> predicate,
P parameter,
R target)
{
for (int i = 0; i < size; i++)
{
T item = array[i];
if (!predicate.accept(item, parameter))
{
target.add(item);
}
}
return target;
}
public static FastList selectInstancesOf(Object[] array, int size, Class clazz)
{
FastList results = FastList.newList(size);
for (int i = 0; i < size; i++)
{
Object each = array[i];
if (clazz.isInstance(each))
{
results.add((T) each);
}
}
return results;
}
public static > R collect(
T[] array,
int size,
Function super T, ? extends V> function,
R target)
{
InternalArrayIterate.ensureCapacityForAdditionalSize(size, target);
for (int i = 0; i < size; i++)
{
target.add(function.valueOf(array[i]));
}
return target;
}
/**
* @since 9.1.
*/
public static > R collectWithIndex(
T[] array,
int size,
ObjectIntToObjectFunction super T, ? extends V> function,
R target)
{
InternalArrayIterate.ensureCapacityForAdditionalSize(size, target);
int index = 0;
for (int i = 0; i < size; i++)
{
target.add(function.valueOf(array[i], index++));
}
return target;
}
private static void ensureCapacityForAdditionalSize(int size, Collection> target)
{
if (target instanceof FastList>)
{
((FastList>) target).ensureCapacity(target.size() + size);
}
else if (target instanceof ArrayList)
{
((ArrayList>) target).ensureCapacity(target.size() + size);
}
}
public static > R flatCollect(
T[] array,
int size,
Function super T, ? extends Iterable> function,
R target)
{
for (int i = 0; i < size; i++)
{
Iterate.addAllTo(function.valueOf(array[i]), target);
}
return target;
}
public static > R collectWith(
T[] array,
int size,
Function2 super T, ? super P, ? extends V> function,
P parameter,
R target)
{
InternalArrayIterate.ensureCapacityForAdditionalSize(size, target);
for (int i = 0; i < size; i++)
{
target.add(function.value(array[i], parameter));
}
return target;
}
public static > R collectIf(
T[] array,
int size,
Predicate super T> predicate,
Function super T, ? extends V> function,
R target)
{
for (int i = 0; i < size; i++)
{
T item = array[i];
if (predicate.accept(item))
{
target.add(function.valueOf(item));
}
}
return target;
}
public static T min(T[] array, int size, Comparator super T> comparator)
{
if (size == 0)
{
throw new NoSuchElementException();
}
T min = array[0];
for (int i = 1; i < size; i++)
{
T item = array[i];
if (comparator.compare(item, min) < 0)
{
min = item;
}
}
return min;
}
public static T max(T[] array, int size, Comparator super T> comparator)
{
if (size == 0)
{
throw new NoSuchElementException();
}
T max = array[0];
for (int i = 1; i < size; i++)
{
T item = array[i];
if (comparator.compare(item, max) > 0)
{
max = item;
}
}
return max;
}
public static T min(T[] array, int size)
{
if (size == 0)
{
throw new NoSuchElementException();
}
T min = array[0];
for (int i = 1; i < size; i++)
{
T item = array[i];
if (((Comparable super T>) item).compareTo(min) < 0)
{
min = item;
}
}
return min;
}
public static T max(T[] array, int size)
{
if (size == 0)
{
throw new NoSuchElementException();
}
T max = array[0];
for (int i = 1; i < size; i++)
{
T item = array[i];
if (((Comparable) item).compareTo(max) > 0)
{
max = item;
}
}
return max;
}
public static > T minBy(T[] array, int size, Function super T, ? extends V> function)
{
if (ArrayIterate.isEmpty(array))
{
throw new NoSuchElementException();
}
T min = array[0];
V minValue = function.valueOf(min);
for (int i = 1; i < size; i++)
{
T next = array[i];
V nextValue = function.valueOf(next);
if (nextValue.compareTo(minValue) < 0)
{
min = next;
minValue = nextValue;
}
}
return min;
}
public static > T maxBy(T[] array, int size, Function super T, ? extends V> function)
{
if (ArrayIterate.isEmpty(array))
{
throw new NoSuchElementException();
}
T max = array[0];
V maxValue = function.valueOf(max);
for (int i = 1; i < size; i++)
{
T next = array[i];
V nextValue = function.valueOf(next);
if (nextValue.compareTo(maxValue) > 0)
{
max = next;
maxValue = nextValue;
}
}
return max;
}
public static int count(T[] array, int size, Predicate super T> predicate)
{
int count = 0;
for (int i = 0; i < size; i++)
{
if (predicate.accept(array[i]))
{
count++;
}
}
return count;
}
public static int countWith(T[] array, int size, Predicate2 super T, ? super P> predicate, P parameter)
{
int count = 0;
for (int i = 0; i < size; i++)
{
if (predicate.accept(array[i], parameter))
{
count++;
}
}
return count;
}
public static boolean shortCircuit(
T[] array,
int size,
Predicate super T> predicate,
boolean expected,
boolean onShortCircuit,
boolean atEnd)
{
for (int i = 0; i < size; i++)
{
T each = array[i];
if (predicate.accept(each) == expected)
{
return onShortCircuit;
}
}
return atEnd;
}
public static boolean shortCircuitWith(
T[] array,
int size,
Predicate2 super T, ? super P> predicate2,
P parameter,
boolean expected,
boolean onShortCircuit,
boolean atEnd)
{
for (int i = 0; i < size; i++)
{
T each = array[i];
if (predicate2.accept(each, parameter) == expected)
{
return onShortCircuit;
}
}
return atEnd;
}
public static boolean corresponds(T[] array, int size, OrderedIterable other, Predicate2 super T, ? super P> predicate)
{
if (size != other.size())
{
return false;
}
if (other instanceof RandomAccess)
{
List
otherList = (List
) other;
for (int index = 0; index < size; index++)
{
if (!predicate.accept(array[index], otherList.get(index)))
{
return false;
}
}
return true;
}
Iterator
otherIterator = other.iterator();
for (int index = 0; index < size; index++)
{
if (!predicate.accept(array[index], otherIterator.next()))
{
return false;
}
}
return true;
}
public static boolean anySatisfy(T[] array, int size, Predicate super T> predicate)
{
return InternalArrayIterate.shortCircuit(array, size, predicate, true, true, false);
}
public static boolean anySatisfyWith(T[] array, int size, Predicate2 super T, ? super P> predicate, P parameter)
{
return InternalArrayIterate.shortCircuitWith(array, size, predicate, parameter, true, true, false);
}
public static boolean allSatisfy(T[] array, int size, Predicate super T> predicate)
{
return InternalArrayIterate.shortCircuit(array, size, predicate, false, false, true);
}
public static boolean allSatisfyWith(T[] array, int size, Predicate2 super T, ? super P> predicate, P parameter)
{
return InternalArrayIterate.shortCircuitWith(array, size, predicate, parameter, false, false, true);
}
public static boolean noneSatisfy(T[] array, int size, Predicate super T> predicate)
{
return InternalArrayIterate.shortCircuit(array, size, predicate, true, false, true);
}
public static boolean noneSatisfyWith(T[] array, int size, Predicate2 super T, ? super P> predicate, P parameter)
{
return InternalArrayIterate.shortCircuitWith(array, size, predicate, parameter, true, false, true);
}
public static T detect(T[] array, int size, Predicate super T> predicate)
{
for (int i = 0; i < size; i++)
{
T each = array[i];
if (predicate.accept(each))
{
return each;
}
}
return null;
}
public static T detectWith(T[] array, int size, Predicate2 super T, ? super P> predicate, P parameter)
{
for (int i = 0; i < size; i++)
{
T each = array[i];
if (predicate.accept(each, parameter))
{
return each;
}
}
return null;
}
public static Optional detectOptional(T[] array, int size, Predicate super T> predicate)
{
for (int i = 0; i < size; i++)
{
T each = array[i];
if (predicate.accept(each))
{
return Optional.of(each);
}
}
return Optional.empty();
}
public static Optional detectWithOptional(T[] array, int size, Predicate2 super T, ? super P> predicate, P parameter)
{
for (int i = 0; i < size; i++)
{
T each = array[i];
if (predicate.accept(each, parameter))
{
return Optional.of(each);
}
}
return Optional.empty();
}
public static void appendString(
ListIterable iterable,
T[] array,
int size,
Appendable appendable,
String start,
String separator,
String end)
{
try
{
appendable.append(start);
if (size > 0)
{
appendable.append(IterableIterate.stringValueOfItem(iterable, array[0]));
for (int i = 1; i < size; i++)
{
appendable.append(separator);
appendable.append(IterableIterate.stringValueOfItem(iterable, array[i]));
}
}
appendable.append(end);
}
catch (IOException e)
{
throw new RuntimeException(e);
}
}
public static int detectIndex(T[] objectArray, int size, Predicate super T> predicate)
{
for (int i = 0; i < size; i++)
{
if (predicate.accept(objectArray[i]))
{
return i;
}
}
return -1;
}
public static int detectLastIndex(T[] objectArray, int size, Predicate super T> predicate)
{
for (int i = size - 1; i >= 0; i--)
{
if (predicate.accept(objectArray[i]))
{
return i;
}
}
return -1;
}
public static void forEachWithIndex(T[] objectArray, int size, ObjectIntProcedure super T> objectIntProcedure)
{
for (int i = 0; i < size; i++)
{
objectIntProcedure.value(objectArray[i], i);
}
}
/**
* @deprecated in 7.0.
*/
@Deprecated
public static > R distinct(T[] objectArray, int size, R targetList)
{
MutableSet seenSoFar = Sets.mutable.empty();
for (int i = 0; i < size; i++)
{
T each = objectArray[i];
if (seenSoFar.add(each))
{
targetList.add(each);
}
}
return targetList;
}
/**
* @since 7.0.
*/
public static FastList distinct(T[] objectArray, int size)
{
return InternalArrayIterate.distinct(objectArray, size, FastList.newList());
}
/**
* @since 7.0.
*/
public static FastList distinct(T[] objectArray, int size, HashingStrategy super T> hashingStrategy)
{
MutableSet seenSoFar = UnifiedSetWithHashingStrategy.newSet(hashingStrategy);
FastList result = FastList.newList();
for (int i = 0; i < size; i++)
{
T each = objectArray[i];
if (seenSoFar.add(each))
{
result.add(each);
}
}
return result;
}
public static long sumOfInt(T[] array, int size, IntFunction super T> function)
{
long result = 0L;
for (int i = 0; i < size; i++)
{
result += (long) function.intValueOf(array[i]);
}
return result;
}
public static long sumOfLong(T[] array, int size, LongFunction super T> function)
{
long result = 0L;
for (int i = 0; i < size; i++)
{
result += function.longValueOf(array[i]);
}
return result;
}
public static double sumOfFloat(T[] array, int size, FloatFunction super T> function)
{
double sum = 0.0d;
double compensation = 0.0d;
for (int i = 0; i < size; i++)
{
double adjustedValue = (double) function.floatValueOf(array[i]) - compensation;
double nextSum = sum + adjustedValue;
compensation = nextSum - sum - adjustedValue;
sum = nextSum;
}
return sum;
}
public static double sumOfDouble(T[] array, int size, DoubleFunction super T> function)
{
double sum = 0.0d;
double compensation = 0.0d;
for (int i = 0; i < size; i++)
{
double adjustedValue = function.doubleValueOf(array[i]) - compensation;
double nextSum = sum + adjustedValue;
compensation = nextSum - sum - adjustedValue;
sum = nextSum;
}
return sum;
}
public static MutableObjectLongMap sumByInt(T[] array, int size, Function super T, ? extends V> groupBy, IntFunction super T> function)
{
MutableObjectLongMap result = ObjectLongMaps.mutable.empty();
for (int i = 0; i < size; i++)
{
T item = array[i];
result.addToValue(groupBy.valueOf(item), function.intValueOf(item));
}
return result;
}
public static MutableObjectLongMap sumByLong(T[] array, int size, Function super T, ? extends V> groupBy, LongFunction super T> function)
{
MutableObjectLongMap result = ObjectLongMaps.mutable.empty();
for (int i = 0; i < size; i++)
{
T item = array[i];
result.addToValue(groupBy.valueOf(item), function.longValueOf(item));
}
return result;
}
public static MutableObjectDoubleMap sumByFloat(T[] array, int size, Function super T, ? extends V> groupBy, FloatFunction super T> function)
{
MutableObjectDoubleMap result = ObjectDoubleMaps.mutable.empty();
MutableObjectDoubleMap groupKeyToCompensation = ObjectDoubleMaps.mutable.empty();
for (int i = 0; i < size; i++)
{
T item = array[i];
V groupByKey = groupBy.valueOf(item);
double compensation = groupKeyToCompensation.getIfAbsentPut(groupByKey, 0.0d);
double adjustedValue = function.floatValueOf(item) - compensation;
double nextSum = result.get(groupByKey) + adjustedValue;
groupKeyToCompensation.put(groupByKey, nextSum - result.get(groupByKey) - adjustedValue);
result.put(groupByKey, nextSum);
}
return result;
}
public static MutableObjectDoubleMap sumByDouble(T[] array, int size, Function super T, ? extends V> groupBy, DoubleFunction super T> function)
{
MutableObjectDoubleMap result = ObjectDoubleMaps.mutable.empty();
MutableObjectDoubleMap groupKeyToCompensation = ObjectDoubleMaps.mutable.empty();
for (int i = 0; i < size; i++)
{
T item = array[i];
V groupByKey = groupBy.valueOf(item);
double compensation = groupKeyToCompensation.getIfAbsentPut(groupByKey, 0.0d);
double adjustedValue = function.doubleValueOf(item) - compensation;
double nextSum = result.get(groupByKey) + adjustedValue;
groupKeyToCompensation.put(groupByKey, nextSum - result.get(groupByKey) - adjustedValue);
result.put(groupByKey, nextSum);
}
return result;
}
/**
* @since 8.0
*/
public static IntSummaryStatistics summarizeInt(T[] items, int size, IntFunction super T> function)
{
IntSummaryStatistics stats = new IntSummaryStatistics();
for (int i = 0; i < size; i++)
{
T item = items[i];
stats.accept(function.intValueOf(item));
}
return stats;
}
/**
* @since 8.0
*/
public static DoubleSummaryStatistics summarizeFloat(T[] items, int size, FloatFunction super T> function)
{
DoubleSummaryStatistics stats = new DoubleSummaryStatistics();
for (int i = 0; i < size; i++)
{
T item = items[i];
stats.accept((double) function.floatValueOf(item));
}
return stats;
}
/**
* @since 8.0
*/
public static LongSummaryStatistics summarizeLong(T[] items, int size, LongFunction super T> function)
{
LongSummaryStatistics stats = new LongSummaryStatistics();
for (int i = 0; i < size; i++)
{
T item = items[i];
stats.accept(function.longValueOf(item));
}
return stats;
}
/**
* @since 8.0
*/
public static DoubleSummaryStatistics summarizeDouble(T[] items, int size, DoubleFunction super T> function)
{
DoubleSummaryStatistics stats = new DoubleSummaryStatistics();
for (int i = 0; i < size; i++)
{
T item = items[i];
stats.accept(function.doubleValueOf(item));
}
return stats;
}
/**
* @since 8.0
*/
public static Optional reduce(T[] items, int size, BinaryOperator accumulator)
{
if (size == 0)
{
return Optional.empty();
}
T result = items[0];
for (int i = 1; i < size; i++)
{
result = accumulator.apply(result, items[i]);
}
return Optional.of(result);
}
/**
* @since 8.0
*/
public static R reduceInPlace(T[] items, int size, Collector super T, A, R> collector)
{
A mutableResult = collector.supplier().get();
BiConsumer accumulator = collector.accumulator();
for (int i = 0; i < size; i++)
{
T item = items[i];
accumulator.accept(mutableResult, item);
}
return collector.finisher().apply(mutableResult);
}
/**
* @since 8.0
*/
public static R reduceInPlace(T[] items, int size, Supplier supplier, BiConsumer accumulator)
{
R mutableResult = supplier.get();
for (int i = 0; i < size; i++)
{
T item = items[i];
accumulator.accept(mutableResult, item);
}
return mutableResult;
}
/**
* @since 10.0 - Provided for convenience for array based containers
*/
public static void replaceAll(T[] items, int size, UnaryOperator operator)
{
for (int i = 0; i < size; i++)
{
T item = items[i];
items[i] = operator.apply(item);
}
}
/**
* Adds all array elements to the target Collection that return true when evaluating the specified predicate which is
* supplied each element and its relative index.
*
* @since 11.0
*/
public static , T> R selectWithIndex(
T[] array,
int size,
ObjectIntPredicate super T> predicate,
R target)
{
for (int i = 0; i < size; i++)
{
T item = array[i];
if (predicate.accept(item, i))
{
target.add(item);
}
}
return target;
}
/**
* Adds all array elements to the target Collection that return false when evaluating the specified predicate which is
* supplied each element and its relative index.
*
* @since 11.0
*/
public static , T> R rejectWithIndex(
T[] array,
int size,
ObjectIntPredicate super T> predicate,
R target)
{
for (int i = 0; i < size; i++)
{
T item = array[i];
if (!predicate.accept(item, i))
{
target.add(item);
}
}
return target;
}
}