[英]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
在您的情况下,您可以使用.map
在Stuff
获取值,然后使用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.