我不明白如何使用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();
}
}
答案 0 :(得分:4)
声明您的方法接受与您的方法签名匹配的现有功能接口类型的参数:
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);
答案 1 :(得分:2)
您的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);
}
}
答案 2 :(得分:2)
源代码中缺少MethodParameter
的定义。要与lambda表达式一起使用,它必须是一个功能接口,例如:
@FunctionalInterface
interface MethodParameter {
String apply(Stuff input);
}
(@FunctionalInterface
注释是可选的。)
要使用该方法,您可以从界面调用该方法:
System.out.println(method.apply(stuff));
第三,方法引用总是需要一个上下文。在你的情况下,你必须这样做:
operateListWith(listStuff, this::methodToPassA);
operateListWith(listStuff, this::methodToPassB);
答案 3 :(得分:1)
您不需要创建像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();
}
}