2013-03-05 184 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 
相關問題