【发布时间】:2017-10-11 02:21:52
【问题描述】:
总的来说,我对 lambdas 和 Java8 还很陌生,所以如果这是一个直截了当的问题,我深表歉意。
我目前有一个类,我想用一堆 getter 对它的 final 做一些复杂的匹配:
public final class Foo {
public String getName();
public Type getType();
public List<Bar> getBarList();
....
}
我写了一个小的帮助类来进行匹配:
public class MatchParameter<T> {
boolean expectMatch = true;
T valueToCheck;
public MatchParameter(T value, boolean shouldMatch) {
this.expectMatch = shouldMatch;
this.valueToCheck = value;
}
public boolean matches(Predicate<T> matcher) {
return matcher.test(valueToCheck) == expectMatch;
}
}
然后我有一个地方可以创建各种MatchParameters 用于检查名称或检查List<Bar> 是否包含特定的Bar:
MatchParameter<String> nameParam = new MatchParameter(inputName, shouldMatch);
MatchParameter<Bar> barParam = new MatchParameter(inputBar, shouldMatch);
....
目前,我一直无法记住每个 MatchParameter 正在寻找的内容。最终我的检查代码看起来像:
if(nameParam.matches(name -> currentFoo.getName().matches(name)) {
...
}
if(barParam.matches(bar -> currentFoo.getBarList().contains(bar)) {
...
}
...
在每种情况下,我传递的谓词都是一个 lambda,它有一些 currentFoo.<accessorFns> 的迭代,最终采用类型 T,并返回一个布尔值。我真正想做的是将访问器的逻辑移动到 MatchParameter 的创建中。
有没有一种方法可以指定一个可以在构造时传入的函数指针?我希望它是某种可运行的,需要(Foo,T)。
在 C++ 中,我会在 MatchParameter 的局部变量中添加一个接受两个输入(Foo 和 T)的本地函数指针:
bool (*checkFn)(Foo f, T input);
然后我可以为每个实例创建一个匿名函数,并将我的 MatchParameter matches 实现更新为:
public boolean matches(Foo f) {
return checkFn(f, valueToCheck) == expectMatch;
}
我的实例化是:
MatchParameter<String> nameParam = new MatchParameter<>(
inputName,
shouldMatch,
(Foo f, String input) -> boolean { return f.getName().matches(input); }
);
在 Java 中是否有等效的方法来实现这一点?
【问题讨论】:
-
当然。创建一个接受
Foo和T并返回boolean的接口。在你的构造函数中接受它。 -
我不完全理解你在做什么,但你为什么需要
MatchParameter类?看起来它只是在基本的if语句中增加了更多内容。 -
如果同时定义谓词,第一个参数是多余的。为什么不
new MatchParameter<>(shouldMatch, f -> f.getname().matches(inputName))? -
@shmosel 在这种情况下你是绝对正确的哈。我从我的实际代码中显着简化了它,
MatchParameter实际上也需要知道它与其他(在我的示例中未列出)函数匹配的值。感谢您指出这一点!
标签: java lambda java-8 function-pointers