Java 8 方法引用不满足功能接口契约,但它可以编译。这怎么可能?
在下面的类中,我将方法引用Java 8 方法引用不满足功能接口契约,但它可以编译。这怎么可能?,java-8,java-stream,method-reference,Java 8,Java Stream,Method Reference,在下面的类中,我将方法引用WordCounterEx::acculate作为第二个参数传递给reduce方法。reduce方法的特征是: <U> U reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> combiner); U减少(U标识, 双功能累加器, 二进制运算符组合器); 因此,reduce方法
WordCounterEx::acculate
作为第二个参数传递给reduce方法。reduce方法的特征是:
<U> U reduce(U identity,
BiFunction<U, ? super T, U> accumulator,
BinaryOperator<U> combiner);
U减少(U标识,
双功能累加器,
二进制运算符组合器);
因此,reduce方法的第二个参数必须满足双函数公式。
但传递的累积方法不是双函数(它只有一个参数)。为什么它还在编译
public class WordCounterEx {
private final int counter;
private final boolean lastSpace;
public WordCounterEx(int counter, boolean lastSpace) {
this.counter = counter;
this.lastSpace = lastSpace;
}
public int countWords(Stream<Character> stream) {
WordCounterEx wordCounter = stream.reduce(new WordCounterEx(0, true),
//HOW CAN THIS WORK? here must come BiFunction - R apply(T t, U u);
WordCounterEx::accumulate,
WordCounterEx::combine);
return wordCounter.counter;
}
public WordCounterEx accumulate(Character c) {
if(Character.isWhitespace(c)) {
return lastSpace ?
this :
new WordCounterEx(counter, true);
} else {
return lastSpace ?
new WordCounterEx(counter+1, false) :
this;
}
}
public WordCounterEx combine(WordCounterEx wordCounter) {
return new WordCounterEx(counter + wordCounter.counter
,wordCounter.lastSpace /*does not matter*/);
}
}
公共类WordCounterEx{
专用最终整数计数器;
私有最终布尔空间;
公共WordCounterEx(整型计数器,布尔值lastSpace){
this.counter=计数器;
this.lastSpace=lastSpace;
}
公共整数countWords(流){
WordCounterEx wordCounter=stream.reduce(新的WordCounterEx(0,true)),
//这是怎么工作的呢?这里必须有双功能-R应用(T,U);
累积,
WordCounterEx::combine);
返回wordCounter.counter;
}
public WordCounterEx累加(字符c){
if(字符.isWhitespace(c)){
返回最后的空间?
这:
新单词counterex(counter,true);
}否则{
返回最后的空间?
新的WordCounterEx(计数器+1,false):
这
}
}
公共WordCounterEx组合(WordCounterEx wordCounter){
返回新的WordCounterEx(counter+wordCounter.counter
,wordCounter.lastSpace/*无所谓*/);
}
}
accumulate()
是一个实例方法,您可以通过类名和方法名(而不是实例和方法名)来引用它。因此,如果我想调用您给我的方法,我通常会执行myEx.acculate(myCh)
。因此,我提供了两件事,WordCounterEx
实例和字符。因此,使用这种方式,该方法将被视为双功能
相反,如果您给了我例如this::acculate
,那么调用该方法的对象将被给出(this
),并且它不能再用作BiFunction
(在我的Eclipse中,我得到“类型流中的方法reduce(U,BiFunction,BinaryOperator))的参数不适用(WordCounterEx,this::accumulate,WordCounterEx::combine)”。可将WordCounterEx#countWords
方法重写如下:
public int countWordsWithInstance(Stream<Character> stream) {
WordCounterEx wordCounter = stream.reduce(new WordCounterEx(0, true),
this::accumulate,
WordCounterEx::combine);
return wordCounter.counter;
}
public WordCounterEx accumulate(WordCounterEx wc,Character c) {
if(Character.isWhitespace(c)) {
return wc.lastSpace ?
wc :
new WordCounterEx(wc.counter, true);
} else {
return wc.lastSpace ?
new WordCounterEx(wc.counter+1, false) :
wc;
}
}
public int countWordsWithInstance(流){
WordCounterEx wordCounter=stream.reduce(新的WordCounterEx(0,true)),
这个,积累,,
WordCounterEx::combine);
返回wordCounter.counter;
}
公共WordCounterEx累积(WordCounterEx wc,字符c){
if(字符.isWhitespace(c)){
返回wc.lastSpace?
厕所:
新的WordCounterEx(wc.counter,true);
}否则{
返回wc.lastSpace?
新的WordCounterEx(wc.counter+1,false):
厕所;
}
}
在这种情况下,accumulate方法的签名中必须有WordCounterEx wc
,这是正确的。作为该方法的变体,您可以声明accumulate()
static
,并将其称为WordCounterEx::accumulate
(如您的问题所示)(如您所知,这是因为调用静态
方法时没有对象)。请注意,在Java 8中,您可以将此
作为参数传递,该参数与签名完全匹配:公共WordCounterEx累积(WordCounterEx this,字符c)
。这相当于没有将此作为参数的版本,如问题中所示。