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不包含布尔返回类型。这就是为什么我用谓词(谓词,作为邪教的对比,以消费者的原因,返回一个更适合我布尔值 - 而我忘了最初提及:((()

感谢您的帮助和时间

+0

类似'list.stream()的forEach()'? – Kayaman

+0

为什么它必须是lambda。为什么你不能传入任何类型的函数指针? –

+2

为什么不呢?您是否尝试过适当的功能界面类型?像'Comsumer '? –

!你不应该混淆的方式,你通话的方法,这可能会或可能不会涉及拉姆达的方式,以及你的方法,其中包括寻找合适的参数类型。

当你写一个方法,你需要关注你的参数的类型,如果其中一个是表示函数的对象,你需要的是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); 
} 
+0

这是正确的答案。另外,我忘记了返回值。这最终导致我被预测而不是消费者。无论如何,解释都是重点。 – xanmcgregor