下面列出了怎么用java.util.function.BinaryOperator的API类实例代码及写法,或者点击链接到github查看源代码。
public void testDoubleMethods() {
BinaryOperator<Double> sum1 = Double::sum;
DoubleBinaryOperator sum2 = Double::sum;
BinaryOperator<Double> max1 = Double::max;
DoubleBinaryOperator max2 = Double::max;
BinaryOperator<Double> min1 = Double::min;
DoubleBinaryOperator min2 = Double::min;
Comparator<Double> cmp = Double::compare;
double[] numbers = { -1, 0, 1, 100, Double.MAX_VALUE, Double.MIN_VALUE };
for (double i : numbers) {
for (double j : numbers) {
assertEquals(i+j, (double) sum1.apply(i, j));
assertEquals(i+j, sum2.applyAsDouble(i, j));
assertEquals(Math.max(i,j), (double) max1.apply(i, j));
assertEquals(Math.max(i,j), max2.applyAsDouble(i, j));
assertEquals(Math.min(i,j), (double) min1.apply(i, j));
assertEquals(Math.min(i,j), min2.applyAsDouble(i, j));
assertEquals(((Double) i).compareTo(j), cmp.compare(i, j));
}
}
}
/**
* Compute the cpu resources required for all the minor fragments of this major fragment.
* This information is stored per DrillbitEndpoint. It is assumed that this function is
* called only once.
*/
public void computeCpuResources() {
Preconditions.checkArgument(nodeResourceMap == null);
BinaryOperator<NodeResource> merge = (first, second) -> {
NodeResource result = NodeResource.create();
result.add(first);
result.add(second);
return result;
};
Function<DrillbitEndpoint, NodeResource> cpuPerEndpoint = (endpoint) -> new NodeResource(1, 0);
nodeResourceMap = endpoints.stream()
.collect(Collectors.groupingBy(Function.identity(),
Collectors.reducing(NodeResource.create(),
cpuPerEndpoint, merge)));
}
public static void main(String[] args) {
int x = Integer.MAX_VALUE;
int y = Integer.MAX_VALUE;
int z = x + y;
System.out.println(x + " + " + y + " via '+' operator is: " + z);
int zSum = Integer.sum(x, y);
System.out.println(x + " + " + y + " via Integer.sum() is: " + zSum);
// throw ArithmeticException
int zExact = Math.addExact(x, y);
System.out.println(x + " + " + y + " via Math.addExact() is: " + zExact);
// throw ArithmeticException
BinaryOperator<Integer> operator = Math::addExact;
int zExactBo = operator.apply(x, y);
System.out.println(x + " + " + y + " via BinaryOperator is: " + zExactBo);
}
public void testFloatMethods() {
BinaryOperator<Float> sum1 = Float::sum;
BinaryOperator<Float> max1 = Float::max;
BinaryOperator<Float> min1 = Float::min;
Comparator<Float> cmp = Float::compare;
float[] numbers = { -1, 0, 1, 100, Float.MAX_VALUE, Float.MIN_VALUE };
for (float i : numbers) {
for (float j : numbers) {
assertEquals(i+j, (float) sum1.apply(i, j));
assertEquals(Math.max(i,j), (float) max1.apply(i, j));
assertEquals(Math.min(i,j), (float) min1.apply(i, j));
assertEquals(((Float) i).compareTo(j), cmp.compare(i, j));
}
}
}
public void testBooleanMethods() {
BinaryOperator<Boolean> and = Boolean::logicalAnd;
BinaryOperator<Boolean> or = Boolean::logicalOr;
BinaryOperator<Boolean> xor = Boolean::logicalXor;
Comparator<Boolean> cmp = Boolean::compare;
assertTrue(and.apply(true, true));
assertFalse(and.apply(true, false));
assertFalse(and.apply(false, true));
assertFalse(and.apply(false, false));
assertTrue(or.apply(true, true));
assertTrue(or.apply(true, false));
assertTrue(or.apply(false, true));
assertFalse(or.apply(false, false));
assertFalse(xor.apply(true, true));
assertTrue(xor.apply(true, false));
assertTrue(xor.apply(false, true));
assertFalse(xor.apply(false, false));
assertEquals(Boolean.TRUE.compareTo(Boolean.TRUE), cmp.compare(true, true));
assertEquals(Boolean.TRUE.compareTo(Boolean.FALSE), cmp.compare(true, false));
assertEquals(Boolean.FALSE.compareTo(Boolean.TRUE), cmp.compare(false, true));
assertEquals(Boolean.FALSE.compareTo(Boolean.FALSE), cmp.compare(false, false));
}
/**
* Returns a new {@code Collector} described by the given {@code supplier},
* {@code accumulator}, {@code combiner}, and {@code finisher} functions.
*
* @param supplier The supplier function for the new collector
* @param accumulator The accumulator function for the new collector
* @param combiner The combiner function for the new collector
* @param finisher The finisher function for the new collector
* @param characteristics The collector characteristics for the new
* collector
* @param <T> The type of input elements for the new collector
* @param <A> The intermediate accumulation type of the new collector
* @param <R> The final result type of the new collector
* @throws NullPointerException if any argument is null
* @return the new {@code Collector}
*/
public static<T, A, R> Collector<T, A, R> of(Supplier<A> supplier,
BiConsumer<A, T> accumulator,
BinaryOperator<A> combiner,
Function<A, R> finisher,
Characteristics... characteristics) {
Objects.requireNonNull(supplier);
Objects.requireNonNull(accumulator);
Objects.requireNonNull(combiner);
Objects.requireNonNull(finisher);
Objects.requireNonNull(characteristics);
Set<Characteristics> cs = Collectors.CH_NOID;
if (characteristics.length > 0) {
cs = EnumSet.noneOf(Characteristics.class);
Collections.addAll(cs, characteristics);
cs = Collections.unmodifiableSet(cs);
}
return new Collectors.CollectorImpl<>(supplier, accumulator, combiner, finisher, cs);
}
public static final Collector<ExecutionResult, InterrimResult, ExecutionResult> sumUpResults() {
final Supplier<InterrimResult> supplier = () -> new InterrimResult();
final BiConsumer<InterrimResult, ExecutionResult> accumulator = (x, y) -> {
x.successCount += y.getSuccessCount();
x.failureCount += y.getFailureCount();
};
final BinaryOperator<InterrimResult> combiner = (x, y) -> new InterrimResult(x.successCount + y.successCount, x.failureCount + y.failureCount);
final Function<InterrimResult, ExecutionResult> finisher = x -> new ExecutionResult(x.successCount, x.failureCount);
return Collector.of(
supplier,
accumulator,
combiner,
finisher,
Collector.Characteristics.UNORDERED);
}
/**
* Returns a new {@code Collector} described by the given {@code supplier},
* {@code accumulator}, {@code combiner}, and {@code finisher} functions.
*
* @param supplier The supplier function for the new collector
* @param accumulator The accumulator function for the new collector
* @param combiner The combiner function for the new collector
* @param finisher The finisher function for the new collector
* @param characteristics The collector characteristics for the new
* collector
* @param <T> The type of input elements for the new collector
* @param <A> The intermediate accumulation type of the new collector
* @param <R> The final result type of the new collector
* @throws NullPointerException if any argument is null
* @return the new {@code Collector}
*/
public static<T, A, R> Collector<T, A, R> of(Supplier<A> supplier,
BiConsumer<A, T> accumulator,
BinaryOperator<A> combiner,
Function<A, R> finisher,
Characteristics... characteristics) {
Objects.requireNonNull(supplier);
Objects.requireNonNull(accumulator);
Objects.requireNonNull(combiner);
Objects.requireNonNull(finisher);
Objects.requireNonNull(characteristics);
Set<Characteristics> cs = Collectors.CH_NOID;
if (characteristics.length > 0) {
cs = EnumSet.noneOf(Characteristics.class);
Collections.addAll(cs, characteristics);
cs = Collections.unmodifiableSet(cs);
}
return new Collectors.CollectorImpl<>(supplier, accumulator, combiner, finisher, cs);
}
public void testLongMethods() {
BinaryOperator<Long> sum1 = Long::sum;
LongBinaryOperator sum2 = Long::sum;
BinaryOperator<Long> max1 = Long::max;
LongBinaryOperator max2 = Long::max;
BinaryOperator<Long> min1 = Long::min;
LongBinaryOperator min2 = Long::min;
Comparator<Long> cmp = Long::compare;
long[] numbers = { -1, 0, 1, 100, Long.MAX_VALUE, Long.MIN_VALUE };
for (long i : numbers) {
for (long j : numbers) {
assertEquals(i+j, (long) sum1.apply(i, j));
assertEquals(i+j, sum2.applyAsLong(i, j));
assertEquals(Math.max(i,j), (long) max1.apply(i, j));
assertEquals(Math.max(i,j), max2.applyAsLong(i, j));
assertEquals(Math.min(i,j), (long) min1.apply(i, j));
assertEquals(Math.min(i,j), min2.applyAsLong(i, j));
assertEquals(((Long) i).compareTo(j), cmp.compare(i, j));
}
}
}
@Test(dataProvider="stringSet")
public void testParallelPrefixForStringr(String[] data , int fromIndex, int toIndex, BinaryOperator<String> op) {
String[] sequentialResult = data.clone();
for (int index = fromIndex + 1; index < toIndex; index++) {
sequentialResult[index ] = op.apply(sequentialResult[index - 1], sequentialResult[index]);
}
String[] parallelResult = data.clone();
Arrays.parallelPrefix(parallelResult, fromIndex, toIndex, op);
assertEquals(parallelResult, sequentialResult);
String[] parallelRangeResult = Arrays.copyOfRange(data, fromIndex, toIndex);
Arrays.parallelPrefix(parallelRangeResult, op);
assertEquals(parallelRangeResult, Arrays.copyOfRange(sequentialResult, fromIndex, toIndex));
}
private static BinaryOperator<SymbolDependency> guardedMerge(BinaryOperator<SymbolDependency> original) {
return (a, b) -> {
if (a.getVersion().equals(b.getVersion())) {
return b;
} else {
return original.apply(a, b);
}
};
}
/** Root task constructor */
public CumulateTask(CumulateTask<T> parent,
BinaryOperator<T> function,
T[] array, int lo, int hi) {
super(parent);
this.function = function; this.array = array;
this.lo = this.origin = lo; this.hi = this.fence = hi;
int p;
this.threshold =
(p = (hi - lo) / (ForkJoinPool.getCommonPoolParallelism() << 3))
<= MIN_PARTITION ? MIN_PARTITION : p;
}
public static <T> Optional<T> combine(Optional<T> left, Optional<T> right, BinaryOperator<T> combiner)
{
if (left.isPresent() && right.isPresent()) {
return Optional.of(combiner.apply(left.get(), right.get()));
}
else if (left.isPresent()) {
return left;
}
else {
return right;
}
}
@Override
public final <R> R collect(Supplier<R> supplier,
ObjIntConsumer<R> accumulator,
BiConsumer<R, R> combiner) {
Objects.requireNonNull(combiner);
BinaryOperator<R> operator = (left, right) -> {
combiner.accept(left, right);
return left;
};
return evaluate(ReduceOps.makeInt(supplier, accumulator, operator));
}
/** Root task constructor */
public CumulateTask(CumulateTask<T> parent,
BinaryOperator<T> function,
T[] array, int lo, int hi) {
super(parent);
this.function = function; this.array = array;
this.lo = this.origin = lo; this.hi = this.fence = hi;
int p;
this.threshold =
(p = (hi - lo) / (ForkJoinPool.getCommonPoolParallelism() << 3))
<= MIN_PARTITION ? MIN_PARTITION : p;
}
/**
* Constructs a {@code TerminalOp} that implements a mutable reduce on
* {@code int} values.
*
* @param <R> The type of the result
* @param supplier a factory to produce a new accumulator of the result type
* @param accumulator a function to incorporate an int into an
* accumulator
* @param combiner a function to combine an accumulator into another
* @return A {@code ReduceOp} implementing the reduction
*/
public static <R> TerminalOp<Integer, R>
makeInt(Supplier<R> supplier,
ObjIntConsumer<R> accumulator,
BinaryOperator<R> combiner) {
Objects.requireNonNull(supplier);
Objects.requireNonNull(accumulator);
Objects.requireNonNull(combiner);
class ReducingSink extends Box<R>
implements AccumulatingSink<Integer, R, ReducingSink>, Sink.OfInt {
@Override
public void begin(long size) {
state = supplier.get();
}
@Override
public void accept(int t) {
accumulator.accept(state, t);
}
@Override
public void combine(ReducingSink other) {
state = combiner.apply(state, other.state);
}
}
return new ReduceOp<Integer, R, ReducingSink>(StreamShape.INT_VALUE) {
@Override
public ReducingSink makeSink() {
return new ReducingSink();
}
};
}
/**
* Constructs a {@code TerminalOp} that implements a mutable reduce on
* {@code double} values.
*
* @param <R> the type of the result
* @param supplier a factory to produce a new accumulator of the result type
* @param accumulator a function to incorporate an int into an
* accumulator
* @param combiner a function to combine an accumulator into another
* @return a {@code TerminalOp} implementing the reduction
*/
public static <R> TerminalOp<Double, R>
makeDouble(Supplier<R> supplier,
ObjDoubleConsumer<R> accumulator,
BinaryOperator<R> combiner) {
Objects.requireNonNull(supplier);
Objects.requireNonNull(accumulator);
Objects.requireNonNull(combiner);
class ReducingSink extends Box<R>
implements AccumulatingSink<Double, R, ReducingSink>, Sink.OfDouble {
@Override
public void begin(long size) {
state = supplier.get();
}
@Override
public void accept(double t) {
accumulator.accept(state, t);
}
@Override
public void combine(ReducingSink other) {
state = combiner.apply(state, other.state);
}
}
return new ReduceOp<Double, R, ReducingSink>(StreamShape.DOUBLE_VALUE) {
@Override
public ReducingSink makeSink() {
return new ReducingSink();
}
};
}
public static <K, V> Collector<Entry<K, V>, MultivaluedMap<K, V>, MultivaluedMap<K, V>> toMultivaluedMap() {
return new Collector<Entry<K, V>, MultivaluedMap<K, V>, MultivaluedMap<K, V>>() {
@Override
public Supplier<MultivaluedMap<K, V>> supplier() {
return MultivaluedHashMap::new;
}
@Override
public BiConsumer<MultivaluedMap<K, V>, Entry<K, V>> accumulator() {
return (map, entry) -> map.add(entry.getKey(), entry.getValue());
}
@Override
public BinaryOperator<MultivaluedMap<K, V>> combiner() {
return (a, b) -> {
a.putAll(b);
return a;
};
}
@Override
public Function<MultivaluedMap<K, V>, MultivaluedMap<K, V>> finisher() {
return Function.identity();
}
@Override
public Set<Characteristics> characteristics() {
return singleton(IDENTITY_FINISH);
}
};
}
@Test(dataProvider="stringSet")
public void testParallelPrefixForStringr(String[] data , int fromIndex, int toIndex, BinaryOperator<String> op) {
String[] sequentialResult = data.clone();
for (int index = fromIndex + 1; index < toIndex; index++) {
sequentialResult[index ] = op.apply(sequentialResult[index - 1], sequentialResult[index]);
}
String[] parallelResult = data.clone();
Arrays.parallelPrefix(parallelResult, fromIndex, toIndex, op);
assertEquals(parallelResult, sequentialResult);
String[] parallelRangeResult = Arrays.copyOfRange(data, fromIndex, toIndex);
Arrays.parallelPrefix(parallelRangeResult, op);
assertEquals(parallelRangeResult, Arrays.copyOfRange(sequentialResult, fromIndex, toIndex));
}
@Override
public final <R> R collect(Supplier<R> supplier,
ObjLongConsumer<R> accumulator,
BiConsumer<R, R> combiner) {
Objects.requireNonNull(combiner);
BinaryOperator<R> operator = (left, right) -> {
combiner.accept(left, right);
return left;
};
return evaluate(ReduceOps.makeLong(supplier, accumulator, operator));
}
@Override
public final <R> R collect(Supplier<R> supplier,
ObjLongConsumer<R> accumulator,
BiConsumer<R, R> combiner) {
BinaryOperator<R> operator = (left, right) -> {
combiner.accept(left, right);
return left;
};
return evaluate(ReduceOps.makeLong(supplier, accumulator, operator));
}
CollectorTask(PipelineHelper<P_OUT> helper,
Spliterator<P_IN> spliterator,
LongFunction<T_BUILDER> builderFactory,
BinaryOperator<T_NODE> concFactory) {
super(helper, spliterator);
this.helper = helper;
this.builderFactory = builderFactory;
this.concFactory = concFactory;
}
CollectorTask(PipelineHelper<P_OUT> helper,
Spliterator<P_IN> spliterator,
LongFunction<T_BUILDER> builderFactory,
BinaryOperator<T_NODE> concFactory) {
super(helper, spliterator);
this.helper = helper;
this.builderFactory = builderFactory;
this.concFactory = concFactory;
}
CollectorImpl(Supplier<A> supplier,
BiConsumer<A, T> accumulator,
BinaryOperator<A> combiner,
Function<A,R> finisher,
Set<Characteristics> characteristics) {
this.supplier = supplier;
this.accumulator = accumulator;
this.combiner = combiner;
this.finisher = finisher;
this.characteristics = characteristics;
}
/**
* Constructs a {@code TerminalOp} that implements a mutable reduce on
* reference values.
*
* @param <T> the type of the input elements
* @param <I> the type of the intermediate reduction result
* @param collector a {@code Collector} defining the reduction
* @return a {@code ReduceOp} implementing the reduction
*/
public static <T, I> TerminalOp<T, I>
makeRef(Collector<? super T, I, ?> collector) {
Supplier<I> supplier = Objects.requireNonNull(collector).supplier();
BiConsumer<I, ? super T> accumulator = collector.accumulator();
BinaryOperator<I> combiner = collector.combiner();
class ReducingSink extends Box<I>
implements AccumulatingSink<T, I, ReducingSink> {
@Override
public void begin(long size) {
state = supplier.get();
}
@Override
public void accept(T t) {
accumulator.accept(state, t);
}
@Override
public void combine(ReducingSink other) {
state = combiner.apply(state, other.state);
}
}
return new ReduceOp<T, I, ReducingSink>(StreamShape.REFERENCE) {
@Override
public ReducingSink makeSink() {
return new ReducingSink();
}
@Override
public int getOpFlags() {
return collector.characteristics().contains(Collector.Characteristics.UNORDERED)
? StreamOpFlag.NOT_ORDERED
: 0;
}
};
}
@Override
public final <R> R collect(Supplier<R> supplier,
ObjIntConsumer<R> accumulator,
BiConsumer<R, R> combiner) {
BinaryOperator<R> operator = (left, right) -> {
combiner.accept(left, right);
return left;
};
return evaluate(ReduceOps.makeInt(supplier, accumulator, operator));
}
/** Root task constructor */
public CumulateTask(CumulateTask<T> parent,
BinaryOperator<T> function,
T[] array, int lo, int hi) {
super(parent);
this.function = function; this.array = array;
this.lo = this.origin = lo; this.hi = this.fence = hi;
int p;
this.threshold =
(p = (hi - lo) / (ForkJoinPool.getCommonPoolParallelism() << 3))
<= MIN_PARTITION ? MIN_PARTITION : p;
}
/** Subtask constructor */
CumulateTask(CumulateTask<T> parent, BinaryOperator<T> function,
T[] array, int origin, int fence, int threshold,
int lo, int hi) {
super(parent);
this.function = function; this.array = array;
this.origin = origin; this.fence = fence;
this.threshold = threshold;
this.lo = lo; this.hi = hi;
}
CollectorImpl(Supplier<A> supplier,
BiConsumer<A, T> accumulator,
BinaryOperator<A> combiner,
Function<A,R> finisher,
Set<Characteristics> characteristics) {
this.supplier = supplier;
this.accumulator = accumulator;
this.combiner = combiner;
this.finisher = finisher;
this.characteristics = characteristics;
}
private void compact(List<InstanceEvent> events) {
BinaryOperator<InstanceEvent> latestEvent = (e1, e2) -> e1.getVersion() > e2.getVersion() ? e1 : e2;
Map<Class<?>, Optional<InstanceEvent>> latestPerType = events.stream()
.collect(groupingBy(InstanceEvent::getClass,
reducing(latestEvent)));
events.removeIf((e) -> !Objects.equals(e, latestPerType.get(e.getClass()).orElse(null)));
}