繁体   English   中英

如何在Java 8中将方法作为参数传递?

[英]How do I pass a method as a parameter in Java 8?

我不明白如何使用lambdas将方法作为参数传递。

考虑以下(不编译)代码,如何完成它以使其工作?

public class DumbTest {
    public class Stuff {
        public String getA() {
            return "a";
        }
        public String getB() {
            return "b";
        }
    }

    public String methodToPassA(Stuff stuff) {
        return stuff.getA();
    }

    public String methodToPassB(Stuff stuff) {
        return stuff.getB();
    }

    //MethodParameter is purely used to be comprehensive, nothing else...
    public void operateListWith(List<Stuff> listStuff, MethodParameter method) {
        for (Stuff stuff : listStuff) {
            System.out.println(method(stuff));
        }
    }

    public DumbTest() {
        List<Stuff> listStuff = new ArrayList<>();
        listStuff.add(new Stuff());
        listStuff.add(new Stuff());

        operateListWith(listStuff, methodToPassA);
        operateListWith(listStuff, methodToPassB);
    }

    public static void main(String[] args) {
        DumbTest l = new DumbTest();

    }
}

声明您的方法接受与您的方法签名匹配的现有功能接口类型的参数:

public void operateListWith(List<Stuff> listStuff, Function<Stuff, String> method) {
    for (Stuff stuff : listStuff) {
        System.out.println(method.apply(stuff));
    }
}

并称之为:

operateListWith(listStuff, this::methodToPassA);

作为进一步的见解,您不需要方法methodToPassA的间接:

operateListWith(listStuff, Stuff::getA);

您的MethodParameter应该是您使用单个方法定义的某个接口。 这被称为功能接口。 然后,您可以传递您的方法。快速演示:

public interface Test{
    void methodToPass(string stuff);
}

[...]

public class DumbTest{
     //MethodParameter is purely used to be comprehensive, nothing else...
    public void operateListWith(List<Stuff> listStuff, Test method) {
        for (Stuff stuff : listStuff) {
            System.out.println(method(stuff));
        }
    }
    public DumbTest() {
        List<Stuff> listStuff = new ArrayList<>();
        //fill list
        operateListWith(listStuff, methodToPassA);
        operateListWith(listStuff, methodToPassB);
    }
}

您的源代码中缺少MethodParameter的定义。 要与lambda表达式一起使用,它必须是一个功能接口,例如:

@FunctionalInterface
interface MethodParameter {
    String apply(Stuff input);
}

@FunctionalInterface注释是可选的。)

要使用该方法,您可以从界面调用该方法:

System.out.println(method.apply(stuff));

第三,方法引用总是需要一个上下文。 在你的情况下你必须这样做:

operateListWith(listStuff, this::methodToPassA);
operateListWith(listStuff, this::methodToPassB);

您需要使用方法引用。

你不需要创建像operateListWith这样的方法,这就是整个想法。 相反,您可以通过执行以下操作来使用forEach对每个值进行操作:

listStuff.stream.forEach(object::methodToPassA);

例如:

public class StreamExample {
  public static void main(String[] args) {
    List<String> list = Arrays.asList("Hello", "What's Up?", "GoodBye");
    list.stream().forEach(System.out::println);
  }
}

输出:

Hello
What's Up?
GoodBye

在您的情况下,您可以使用.mapStuff获取值,然后使用forEach对其进行操作,如下所示:

public class DumbTest {
  public class Stuff {
    public String getA() {
      return "a";
    }

    public String getB() {
      return "b";
    }
  }

  public String methodToPassA(Stuff stuff) {
    return stuff.getA();
  }

  public String methodToPassB(Stuff stuff) {
    return stuff.getA();
  }

  public DumbTest() {
    List<Stuff> listStuff = Arrays.asList(new Stuff(), new Stuff());

    listStuff.stream()
        .map(this::methodToPassA)
        .forEach(System.out::println);
  }

  public static void main(String[] args) {
    DumbTest l = new DumbTest();
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM