我遇到了一个问题,其中我的类包含多个具有大量重复代码的方法。这背后的原因是每个方法遍历一个条目列表并调用特定的入口方法。
在代码中......
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
Jorn Vernee 和 Joffrey 提供的答案是正确的!
最终,解决方案是使用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
}
编辑2
我在HighLevelClass中的初始方法不包含布尔返回类型。这就是为什么我使用谓词(Predicate,作为对消费者的影响,返回适合我的布尔值更好 - 而且我忘了最初提到的:((()
感谢您的帮助和时间!
答案 0 :(得分:2)
你不应该混淆调用方法的方式,这可能涉及或不涉及lambda,以及编写方法的方式,这涉及到找到正确的方法参数类型。
当你编写一个方法时,你需要关注你的论点&#39;类型。如果其中一个是表示函数的对象,那么您需要了解此函数应该匹配的相应签名,这将为您提供应作为参数类型放置的函数接口。
在您的情况下,您期望一个函数采用类型LowLevelClass
的1个参数并且不返回任何值。您可能会对此感到惊讶,但您需要将实例方法视为将类的实例(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);
}