我想写一种功能工厂。它应该是一个函数,该函数曾经被称为不同的策略作为参数。它应该返回一个函数,该函数根据谓词来选择依赖于参数的策略之一。好吧,多看看condition3
可以更好地理解。问题是,它没有编译。我认为由于编译器无法弄清楚,功能接口H
可以通过实现来实现。没有泛型,它会正常工作。
@FunctionalInterface
public interface Finder<T, S> {
Stream<S> findBest (T t);
// Valid code
static <P, Q> Finder<P, Q> condition1 () {
return p -> null;
}
// Valid code, but selects just one of the H's when the method is invoked
static <P, Q, H extends Finder<P, Q>> H condition2 (Pair<Predicate<P>, H>... hs) {
return hs[0].getRight ();
}
// Should return a method, which selects the appropiate H
// whenever it is invoked with an P
// Compiler complain:
// The target type of this expression must be a functional interface
static <P, Q, H extends Finder<P, Q>> H condition3 (Pair<Predicate<P>, H>... hs) {
return p -> stream (hs).filter (pair -> pair.getLeft ().test (p))
.findFirst ()
.map (Pair::getRight)
.map (h -> h.findBest (p))
.orElseGet (Stream::empty);
}
}
那么这是什么问题呢?我可以解决它吗?如果可以,使用Java:如何解决?
查看方法的签名,然后尝试确定确切的返回类型是什么:
static <P, Q, H extends Finder<P, Q>> H condition3(…
Lambda只能interface
在编译时实现已知的。但是H
编译器不知道的实际类型参数。
您的第一个方法起作用是因为它返回Finder<P, Q>
lambda可以实现的类型,而第二个方法是起作用,因为它不使用lambda来实现return type H extends Finder<P, Q>
。
只有第三个方法尝试为类型参数指定lambda表达式H extends Finder<P, Q>
。
解决方案不是让调用者自由地将特定的子类型委托Finder
为方法的返回类型:
static <P, Q, H extends Finder<P, Q>>
Finder<P, Q> condition3(Pair<Predicate<P>, H>... hs) {
为了说明原始方法签名的含义,请看以下示例:
final class HImpl implements Finder<String,String> {
public Stream<String> findBest(String t) {
return null; // just for illustration, we never really use the class
}
}
…
HImpl x=Finder.<String,String,HImpl>condition3();
给定您的原始方法签名,该文件将正确编译。但是该方法应该如何使用lambda表达式在此处condition3
提供实例HImpl
?
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句