Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 8 方法引用不满足功能接口契约,但它可以编译。这怎么可能?_Java 8_Java Stream_Method Reference - Fatal编程技术网

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)
。这相当于没有将此作为参数的版本,如问题中所示。