Java Lambdas:发送方法名称作为参数
我遇到了一个问题,其中我的类包含多个重复代码的方法。其原因是每种方法都会遍历一个条目列表并调用特定的条目方法。Java Lambdas:发送方法名称作为参数
在代码...
的LowLevelClass类具有以下结构:
public class LowLevelClass {
// constructor omitted
public boolean doSomethingA() {
// some non-duplicated code
return true;
}
public boolean doSomethingB() {
// some non-duplicated code
return true;
}
public boolean doSomethingC() {
// some non-duplicated code
return true;
}
}
顶级类包含LowLevelClasses的列表,并具有相同数量的方法,但这个时候,与很多重复的:
public class HighLevelClass {
private List<LowLevelClass> classes = new ArrayList<>();
public HighLevelClass() {
this.classes.add(new LowLevelClass(/* params */));
this.classes.add(new LowLevelClass(/* params */));
this.classes.add(new LowLevelClass(/* params */));
}
public void doA() {
System.out.println("Doing ...");
for (LowLevelClass entry : classes) {
System.out.println("Doing something...");
entry.doSomethingA();
System.out.println("Done");
}
}
public void doB() {
System.out.println("Doing ...");
for (LowLevelClass entry : classes) {
System.out.println("Doing something...");
entry.doSomethingB();
System.out.println("Done");
}
}
public void doC() {
System.out.println("Doing ...");
for (LowLevelClass entry : classes) {
System.out.println("Doing something...");
entry.doSomethingC();
System.out.println("Done");
}
}
}
我的目标是有东西的形式:
public class HighLevelClass {
private List<LowLevelClass> classes = new ArrayList<>();
public HighLevelClass() {
this.classes.add(new LowLevelClass());
this.classes.add(new LowLevelClass());
this.classes.add(new LowLevelClass());
}
public void doSomething(Lambda /* Functional interface*/ operation) {
System.out.println("Doing A");
for (LowLevelClass entry : classes) {
System.out.println("Doing something...");
entry.operation; // or something else...
System.out.println("Done");
}
}
public void doSomethingA() {
// my goal... and maybe in totally wrong direction is to send something in form of...
return doSomething(LowLevelClass::doSomethingA);
}
// etc
}
这可以用Java 8与Lambdas完成吗?换句话说,我可以定义在给定列表的每个条目上执行的方法吗?
编辑1个
通过乔恩Vernee和乔佛里提供的答案是正确的!
最终,解决方案是使用Predicate。 (见编辑2,为什么我没有在结尾处使用消费者...)
公共类HighLevelClass {
private List<LowLevelClass> classes = new ArrayList<>();
public HighLevelClass() {
this.classes.add(new LowLevelClass());
this.classes.add(new LowLevelClass());
this.classes.add(new LowLevelClass());
}
public boolean doSomething(Predicate<LowLevelClass> function) {
System.out.println("Doing A");
for (LowLevelClass entry : classes) {
System.out.println("Doing something...");
boolean val = function.test(entry);
System.out.println("Done " + val);
}
return someEndVerdict;
}
public boolean doSomethingA() {
return doSomething(LowLevelClass::doSomethingA);
}
// etc
}
EDIT 2
我最初的方法HighLevelClass不包含布尔返回类型。这就是为什么我用谓词(谓词,作为邪教的对比,以消费者的原因,返回一个更适合我布尔值 - 而我忘了最初提及:((()
感谢您的帮助和时间
!你不应该混淆的方式,你通话的方法,这可能会或可能不会涉及拉姆达的方式,以及你写的方法,其中包括寻找合适的参数类型。
当你写一个方法,你需要关注你的参数的类型,如果其中一个是表示函数的对象,你需要的是und要知道这个函数应该匹配的适当的签名,并且这会给你作为参数类型的功能界面。
就你而言,你期望一个函数接受1个类型为LowLevelClass
的参数,并且不返回任何值。您可能会对此感到惊讶,但您需要将实例方法看作是将类的实例(this
)作为额外的第一个参数(而不是静态方法)的函数。
因此,Consumer<LowLevelClass>
界面是你想要什么:
public void doSomething(Consumer<LowLevelClass> operation) {
System.out.println("Doing A");
for (LowLevelClass entry : classes) {
System.out.println("Doing something...");
operation.accept(entry); // or something else...
System.out.println("Done");
}
}
public void doSomethingA() {
return doSomething(LowLevelClass::doSomethingA);
}
这是正确的答案。另外,我忘记了返回值。这最终导致我被预测而不是消费者。无论如何,解释都是重点。 – xanmcgregor
类似'list.stream()的forEach()'? – Kayaman
为什么它必须是lambda。为什么你不能传入任何类型的函数指针? –
为什么不呢?您是否尝试过适当的功能界面类型?像'Comsumer'? –