当调用 IntBinaryOperator 的新实例时,ApplyAsInt 如何自动工作?
How does ApplyAsInt work automatically when a new instance of IntBinaryOperator is called?
我完成了一个编程练习,然后检查了其他人的答案。我发现了一个我很难理解的问题。
练习是:"Given a string of uppercase letters, for example ABC, return the number of letters missing"
ABC, returns 0
ABD returns 1, because C is missing
BCF returns 3, because A, D and E are missing.
import java.util.function.IntBinaryOperator;
public class TrainInspector {
static class Op implements IntBinaryOperator {
int prev = 'A';
@Override
public int applyAsInt(int left, int right) {
left += right - prev - 1;
prev = right;
return left;
}
}
public static int countMissingCarriages(String train) {
if ( train == null || train.isEmpty() ) return 0;
return train.chars().reduce(1, new Op());
}
}
我知道 reduce 从给定的参数中为我们提供了一个 int。但是我不明白 applyAsInt 如何在创建新的 IntBinaryOperator 时自动工作。
我已阅读:
http://www.java2s.com/Tutorials/Java/java.util.function/IntBinaryOperator/index.htm
她就是这样使用applyAsInt()
方法
@Override
public final int reduce(int identity, IntBinaryOperator op) {
return evaluate(ReduceOps.makeInt(identity, op));
}
static TerminalOp<Integer, Integer> makeInt(int identity, IntBinaryOperator operator) {
class ReducingSink implements ... {
private int state;
//...
@Override
public void accept(int t) {
state = operator.applyAsInt(state, t); // <----------
}
//...
}
return new ReduceOp<Integer, Integer, ReducingSink>(StreamShape.INT_VALUE) {
@Override
public ReducingSink makeSink() {
return new ReducingSink();
}
};
}
流码为:
train.chars().reduce(1, new Op())
reduce
的 javadoc 说:
Performs a reduction on the elements of this stream, using the provided identity value and an associative accumulation function, and returns the reduced value. This is equivalent to:
int result = identity;
for (int element : this stream)
result = accumulator.applyAsInt(result, element)
return result;
要了解如何在此处使用 Op
,让我们看一下 等效 非流版本的 countMissingCarriages
方法,方法是应用来自javadoc.
public static int countMissingCarriages(String train) {
if ( train == null || train.isEmpty() ) return 0;
// values from stream
char[] stream = train.toCharArray();
// values from 'reduce' parameters
int identity = 1;
IntBinaryOperator accumulator = new Op();
// logic from javadoc
int result = identity;
for (int element : stream)
result = accumulator.applyAsInt(result, element);
return result;
}
希望这有助于澄清事情。
我完成了一个编程练习,然后检查了其他人的答案。我发现了一个我很难理解的问题。
练习是:"Given a string of uppercase letters, for example ABC, return the number of letters missing"
ABC, returns 0
ABD returns 1, because C is missing
BCF returns 3, because A, D and E are missing.
import java.util.function.IntBinaryOperator;
public class TrainInspector {
static class Op implements IntBinaryOperator {
int prev = 'A';
@Override
public int applyAsInt(int left, int right) {
left += right - prev - 1;
prev = right;
return left;
}
}
public static int countMissingCarriages(String train) {
if ( train == null || train.isEmpty() ) return 0;
return train.chars().reduce(1, new Op());
}
}
我知道 reduce 从给定的参数中为我们提供了一个 int。但是我不明白 applyAsInt 如何在创建新的 IntBinaryOperator 时自动工作。
我已阅读:
http://www.java2s.com/Tutorials/Java/java.util.function/IntBinaryOperator/index.htm
她就是这样使用applyAsInt()
方法
@Override
public final int reduce(int identity, IntBinaryOperator op) {
return evaluate(ReduceOps.makeInt(identity, op));
}
static TerminalOp<Integer, Integer> makeInt(int identity, IntBinaryOperator operator) {
class ReducingSink implements ... {
private int state;
//...
@Override
public void accept(int t) {
state = operator.applyAsInt(state, t); // <----------
}
//...
}
return new ReduceOp<Integer, Integer, ReducingSink>(StreamShape.INT_VALUE) {
@Override
public ReducingSink makeSink() {
return new ReducingSink();
}
};
}
流码为:
train.chars().reduce(1, new Op())
reduce
的 javadoc 说:
Performs a reduction on the elements of this stream, using the provided identity value and an associative accumulation function, and returns the reduced value. This is equivalent to:
int result = identity; for (int element : this stream) result = accumulator.applyAsInt(result, element) return result;
要了解如何在此处使用 Op
,让我们看一下 等效 非流版本的 countMissingCarriages
方法,方法是应用来自javadoc.
public static int countMissingCarriages(String train) {
if ( train == null || train.isEmpty() ) return 0;
// values from stream
char[] stream = train.toCharArray();
// values from 'reduce' parameters
int identity = 1;
IntBinaryOperator accumulator = new Op();
// logic from javadoc
int result = identity;
for (int element : stream)
result = accumulator.applyAsInt(result, element);
return result;
}
希望这有助于澄清事情。