在Java8中,如何将方法作为参数传递?

在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

我不明白如何使用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();

    }
}
公共类测试{
公共类的东西{
公共字符串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)”编译错误是的,实际上您需要
。固定的。