Java Lambdas:将方法名称作为参数发送

Java Lambdas:将方法名称作为参数发送,java,lambda,interface,functional-programming,Java,Lambda,Interface,Functional Programming,我遇到了一个问题,在这个问题中,我的类包含多个方法,其中包含大量重复的代码。这背后的原因是每个方法都遍历一个条目列表并调用特定的条目方法 在代码中 LowLevelClass具有以下结构: public class LowLevelClass { // constructor omitted public boolean doSomethingA() { // some non-duplicated code return true;

我遇到了一个问题,在这个问题中,我的类包含多个方法,其中包含大量重复的代码。这背后的原因是每个方法都遍历一个条目列表并调用特定的条目方法

在代码中

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;
    }
}
顶级类包含一个低级类列表,并且具有相同数量的方法,但这一次有很多重复:

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类HighLevelClass{
私有列表类=新的ArrayList();
公共高级类(){
this.classes.add(新的低级类(/*params*/);
this.classes.add(新的低级类(/*params*/);
this.classes.add(新的低级类(/*params*/);
}
公共无效doA(){
System.out.println(“正在…”);
for(低级类条目:类){
System.out.println(“做某事…”);
entry.doSomethingA();
系统输出打印项次(“完成”);
}
}
公屋空置日期({
System.out.println(“正在…”);
for(低级类条目:类){
System.out.println(“做某事…”);
entry.doSomethingB();
系统输出打印项次(“完成”);
}
}
公共文件(){
System.out.println(“正在…”);
for(低级类条目:类){
System.out.println(“做某事…”);
entry.doSomethingC();
系统输出打印项次(“完成”);
}
}
}
我的目标是拥有以下形式的东西:

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
}
public类HighLevelClass{
私有列表类=新的ArrayList();
公共高级类(){
this.classes.add(new LowLevelClass());
this.classes.add(new LowLevelClass());
this.classes.add(new LowLevelClass());
}
公共无效剂量测量(Lambda/*功能接口*/操作){
System.out.println(“做A”);
for(低级类条目:类){
System.out.println(“做某事…”);
entry.operation;//或其他内容。。。
系统输出打印项次(“完成”);
}
}
公共无效doSomethingA(){
//我的目标…也许完全错误的方向是以…的形式发送一些东西。。。
返回doSomething(低级类::doSomethingA);
}
//等
}
这可以在Java8和Lambdas中实现吗?换句话说,我可以定义对给定列表的每个条目执行的方法吗

编辑1

Jorn VerneeJoffrey提供的答案是正确的

最终,解决方案是使用谓词。(参见编辑2为什么我最终没有使用Consumer…)

公共类高级类{

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
private List classes=new ArrayList();
公共高级类(){
this.classes.add(new LowLevelClass());
this.classes.add(new LowLevelClass());
this.classes.add(new LowLevelClass());
}
公共布尔doSomething(谓词函数){
System.out.println(“做A”);
for(低级类条目:类){
System.out.println(“做某事…”);
布尔值=function.test(条目);
系统输出打印项次(“完成”+val);
}
返回某个结果;
}
公共布尔值doSomethingA(){
返回doSomething(低级类::doSomethingA);
}
//等
}

编辑2

我在HighLevelClass中的初始方法不包含布尔返回类型。这就是为什么我使用谓词(Predicate,作为对消费者的一个对比,返回更适合我的布尔值,我一开始忘记提到:()


感谢您的帮助和时间!

您不应该混淆调用方法的方式(可能涉及lambda,也可能不涉及lambda)和编写方法的方式(包括查找正确的参数类型)

编写方法时,需要关注参数的类型。如果其中一个参数是表示函数的对象,则需要了解此函数应匹配的相应签名,这将为您提供作为参数类型的函数接口

在您的例子中,您希望函数接受1个类型为
LowLevelClass
的参数,但不返回任何值。您可能会对此感到惊讶,但您需要将实例方法视为将类的实例(
this
)作为额外第一个参数的函数(与静态方法相反)

因此,
消费者
界面就是您想要的:

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);
}
public void doSomething(消费者操作){
System.out.println(“做A”);
for(低级类条目:类){
System.out.println(“做某事…”);
操作。接受(条目);//或其他内容。。。
系统输出打印项次(“完成”);
}
}
公共无效doSomethingA(){
返回doSomething(低级类::doSomethingA);
}

您不应该混淆调用方法的方式(可能涉及或不涉及lambda)和编写方法的方式(涉及找到正确的参数类型)

编写方法时,需要关注参数的类型。如果其中一个参数是表示函数的对象,则需要了解此函数应匹配的相应签名,这将为您提供作为参数类型的函数接口

在您的例子中,您希望函数接受1个类型为
LowLevelClass
的参数,但不返回任何值。您可能会对此感到惊讶,但您需要将实例方法视为将类的实例(
this
)作为额外第一个参数的函数(与静态方法相反)

因此,
消费者
界面就是您想要的:

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);
}
public void doSomething(消费者操作){
System.out.println(“做A”);
for(低级类条目:类){
System.out.println