在Java8中,如何将方法作为参数传递?
我不明白如何使用lambdas将方法作为参数传递 考虑到以下(非编译)代码,我如何完成它以使其工作在Java8中,如何将方法作为参数传递?,java,lambda,java-8,Java,Lambda,Java 8,我不明白如何使用lambdas将方法作为参数传递 考虑到以下(非编译)代码,我如何完成它以使其工作 public class DumbTest { public class Stuff { public String getA() { return "a"; } public String getB() { return "b"; } } public Str
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();
}
}
公共类测试{
公共类的东西{
公共字符串getA(){
返回“a”;
}
公共字符串getB(){
返回“b”;
}
}
公共字符串methodToPassA(Stuff-Stuff){
返回stuff.getA();
}
公共字符串methodToPassB(Stuff-Stuff){
return stuff.getB();
}
//MethodParameter仅用于全面性,没有其他用途。。。
public void operateListWith(List listStuff,MethodParameter方法){
用于(内容:listStuff){
System.out.println(方法(stuff));
}
}
公共服务测试(){
List listStuff=new ArrayList();
添加(newstuff());
添加(newstuff());
operateListWith(列表、methodToPassA);
operateListWith(listStuff,methodToPassB);
}
公共静态void main(字符串[]args){
DumbTest l=新DumbTest();
}
}
您的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);
}
}
公共接口测试{
void methodToPass(字符串填充);
}
[...]
公开课哑巴测试{
//MethodParameter仅用于全面性,没有其他用途。。。
公共无效操作列表(列表、测试方法){
用于(内容:listStuff){
System.out.println(方法(stuff));
}
}
公共服务测试(){
List listStuff=new ArrayList();
//填写清单
operateListWith(列表、methodToPassA);
operateListWith(listStuff,methodToPassB);
}
}
您需要使用
您不需要创建像operateListWith
这样的方法,这就是整个想法的一部分。相反,您可以使用以下操作对每个值进行操作:
listStuff.stream.forEach(object::methodToPassA);
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();
}
}
例如:
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);
}
}
@FunctionalInterface
interface MethodParameter {
String apply(Stuff input);
}
在您的情况下,您可以使用Stuff
中的值,然后使用forEach
对其进行操作,如下所示:
listStuff.stream.forEach(object::methodToPassA);
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();
}
}
公共类测试{
公共类的东西{
公共字符串getA(){
返回“a”;
}
公共字符串getB(){
返回“b”;
}
}
公共字符串methodToPassA(Stuff-Stuff){
返回stuff.getA();
}
公共字符串methodToPassB(Stuff-Stuff){
返回stuff.getA();
}
公共服务测试(){
List listStuff=Arrays.asList(new Stuff(),new Stuff());
stream()
.map(this::methodtopasa)
.forEach(System.out::println);
}
公共静态void main(字符串[]args){
DumbTest l=新DumbTest();
}
}
源代码中缺少MethodParameter
的定义。要与lambda表达式一起使用,它必须是函数接口,例如:
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);
}
}
@FunctionalInterface
interface MethodParameter {
String apply(Stuff input);
}
(@functioninterface
注释是可选的。)
要使用该方法,您必须从接口调用该方法:
System.out.println(method.apply(stuff));
第三,方法引用总是需要上下文。在您的情况下,您必须:
operateListWith(listStuff, this::methodToPassA);
operateListWith(listStuff, this::methodToPassB);
声明方法以接受与方法签名匹配的现有函数接口类型的参数:
public void operateListWith(List<Stuff> listStuff, Function<Stuff, String> method) {
for (Stuff stuff : listStuff) {
System.out.println(method.apply(stuff));
}
}
进一步了解,您不需要间接使用methodtopasa
:
operateListWith(listStuff, Stuff::getA);
lambda只使用功能接口(只有一种方法的接口
,如Runnable
)。我没有看到您声明功能接口。另外,当你遇到错误时,告诉我们你遇到了什么错误以及错误在哪里。我没有贴出一个功能界面,因为我在写这篇文章时不理解它。。这段代码不是编译的,它必须作为某些部分的伪代码读取。您为什么要这样做?为什么不直接执行listStuff.stream().map(method).forEach(System.out::println)
?这不是lambdas的全部要点吗?实际上我更喜欢OP的学习方式:将lambda(一种语言特性)与Streams(一种使用它的API)分离。lambda是一个比streamsapi更广泛的故事。是的,在生产代码中,您可以按照自己的方式编写。我不使用stream,因为我想了解如何将方法作为参数传递,正如Marko猜测的那样,这不是这样工作的;我得到“type函数中的方法apply(String)不适用于参数(DumbTest.Stuff)”编译错误是的,实际上您需要
。固定的。