2013-03-05 193 views
1

我的collect()函数调用Foo.f()。我想让Foo.f()本身成为我的功能的一个参数。这在Java中可能吗?如何在java中将成员函数作为参数传递?

  • 如何传递要么Foo.f()Foo.g()(或Foo任何其他函数返回一个String)到我的功能?
  • 是否存在一个已存在的函数,该函数会遍历一个集合并收集调用每个集合项的方法的结果?

class Foo { 
    public String f() { return "f"; } 
    public String g() { return "g"; } 
    // ... 
} 

public List<String> collect(List<Foo> foos) 
{ 
    List<String> result = new ArrayList<String>(); 

    for (final Foo foo: foos) { 
     result.add(foo.f()); // I want Foo.f to be a parameter 
    } 

    return result; 
} 

更新

我想指出的事实,我不只是调用同一个功能,而是为List<Foo>集合中的所有项目成员函数f

+0

您始终可以使用反射API并传递一个Method对象。 – duffymo 2013-03-05 16:19:31

+0

或者你可以创建一个接口... – pamphlet 2013-03-05 16:20:20

+2

查看[Command Pattern](http://en.wikipedia.org/wiki/Command_pattern)。函数指针在java中不存在,除了用反射 – 2013-03-05 16:20:26

回答

7

在Java 8,你可以做

collect(foos, Foo::f); 

public List<String> collect(List<Foo> foos, Function<Foo,String> func) 
{ 
    List<String> result = new ArrayList<String>(); 

    for (final Foo foo: foos) { 
     result.add(func.apply(foo)); 
    } 

    return result; 
} 

或用蒸汽API

Stream<Foo> foos = ...; 
Stream<String> strs = foos.map(Foo::f); 
+0

Java 8目前还不完全稳定。在Java的早期版本中,不支持闭包和函数指针。 – RudolphEst 2013-03-05 16:27:47

+0

@RudolphEst但是,如果你问这个问题,你可能暂时不会生产很多软件。现在不妨使用Java SE 8。/Java SE 8没有函数指针,而且“lambdas”实际上不再是匿名内部类的闭包(关键是语法不那么冗长)。 – 2013-03-05 16:43:51

+0

@ TomHawtin-tackline它取决于。如果OP是大学的学生,他可能会受限于在他的项目中使用Java 7。 – RudolphEst 2013-03-05 16:51:01

6

可以使用接口

interface Foo 
    { 
     String fn(); 
    } 

和接口传递到方法

void anyMethod(Foo f) 
{ 
    f.fn(); 
} 

你不需要创建一个具体的Foo,只需创建Foo匿名

new Foo() { 

    @Override 
    public String fn() 
    { 
    return "something"; 
    } 
}; 

在Java 8你不需要匿名即时通讯使界面更加美观。您可以改用lambda表达式。

anyMethod(()-> "something"); 
+0

我不明白,这个解决方案如何与'collect( )'因为我不是简单地调用相同的函数,而是为集合的*不同*项目调用相同的函数。 – 2013-03-05 18:00:26

+0

@MichaWiedenmann你可以简单地调用fn中的任何方法() – 2013-03-05 18:58:29

0

在Java中你不应该传递方法作为参数,但是你可以通过一个对象作为参数。

它被称为Strategy Pattern,您将需要使用接口。

0

您可以像使用一个接口:

interface IFoo { 
    String getString(); 
} 

然后实现它的定制方式:

class F implements IFoo { 
    public String getString() { 
     return "f"; 
    } 
} 

class G implements IFoo { 
    public String getString() { 
     return "g"; 
    } 
} 

,有你的函数采取的任何实现IFoo列表:

public List<String> collect(List<? extends IFoo> foos) 
{ 
    List<String> result = new ArrayList<String>(); 

    for (final IFoo foo: foos) { 
     result.add(foo.getString()); 
    } 

    return result; 
} 

用法:

for (String a : collect(Arrays.asList(new F(), new G()))) { 
    System.out.println(a); 
} 
    //Prints f and g 
相关问题