3

我想在一個數組或列表的迭代中計算多個函數,但可能需要動態增加函數列表。例如,我可能想要計算最小值和最大值,然後還需要稍後的平均函數(或任何其他線性複雜度函數)。所以,我可能希望有一個高層次的規格(使用某些功能被稱爲addFunc以及諸如從一個數組迭代中計算多個結果

funcs = emptyFunctionList; # no functions in funcs "list" yet 
funcs = addFunc (min, funcs); # add minimum function 
funcs1 = addFunc (max, funcs); # add maximum function 

answers1 = applyAllFuncs (funcs1, myArray);  

funcs2 = addFunc (avg, funcs); # add average function 

answers2 = applyAllFuncs (funcs2, myArray); 

applyAllFuncs我可以通過創建從這些函數得到一個「superfunction」在函數式語言做到這一點很容易傳遞給foldl,元編程可能是一種機制,可以在Haskell/C++中更高效地執行此操作,但想知道是否有一種有效且不是非常複雜的方式,通常可以完成(或可以完成)標準的Java(不需要大量的模擬/實現更高級別的功能)

回答

0

創建自己的摺疊:
有一個方法需要在列表中運行列表和函數列表。
要在列表中運行的函數列表可以簡單地爲ArrayList<XFunction>,其中XFunction是您定義的具有方法(例如run(...))的類,您可以爲每個函數創建它的匿名實現。

例:

list.add(new XFunction(){ 
    run(ArrayList<int> numbers){ 
     return numbers.size(); 
     } 
    } 

這當然是不能夠解決任何功能,但你的想法

+0

非常感謝您的回答。這樣做的一個意識形態問題是,它正在用命令式語言實施一個功能範式。實際的問題是這會影響執行時間。我不確定使用標準Java(Sun-but-now-Oracle)編譯器對用於實現更高階函數的機器進行了優化(如您所示)。 – KXS 2011-04-08 05:42:10

+0

我知道它們是醜陋的,不衛生的,我根本不是一個大粉絲,它可能是邪惡的,宏觀機制(如C迭代器宏),這將使我能夠簡單地內聯附加結果計算,似乎是我能想到的唯一方法就是解決實際問題。 ...或者我只是沒有足夠的努力。 – KXS 2011-04-08 05:42:10

0

您可以使用某種Stategy模式:

public interface Function{ 
    public void Compute(); 
} 

public Function1 implements Function{ 
    public void Compute(){ 
     System.out.println("This is Function1"); 
    } 
} 

public Function2 implements Function{ 
    public void Compute(){ 
     System.out.println("This is Function2"); 
    } 
} 

後宣佈一個容器的功能:

ArrayList<Function> functions = new ArrayList<Function>(); 
functions.add(new Function1()); 
functions.add(new Function2()); 

ArrayList<Object> someData = new ArrayList<Object>(); 
Something.execute(someData,functions); 
1

這裏是相當於你已經在您的文章中給出的功能僞完整的工作Java代碼:

import java.util.*; 

interface Function1<A, B> { 
    public B apply(final A a); 
} 

class Main { 
    public static <A, B> List<Function1<A, B>> addFunc(final Function1<A, B> f, final List<Function1<A, B>> fs) { 
    final List<Function1<A, B>> gs = new ArrayList<Function1<A, B>>(); 
    gs.addAll(fs); 
    gs.add(f); 
    return gs; 
    } 

    public static <A, B> List<B> applyAllFuncs(final List<Function1<List<A>, B>> fs, final List<A> as) { 
    final List<B> bs = new ArrayList<B>(); 
    for(final Function1<List<A>, B> f : fs) { 
     bs.add(f.apply(as)); 
    } 
    return bs; 
    } 

    public static Function1<List<Double>, Double> min = new Function1<List<Double>, Double>() { 
    public Double apply(final List<Double> xs) { 
     double mx = xs.get(0); 
     for(final Double x : xs) { 
     if(x < mx) { 
      mx = x; 
     } 
     } 
     return mx; 
    } 
    }; 

    public static Function1<List<Double>, Double> avg = new Function1<List<Double>, Double>() { 
    public Double apply(final List<Double> xs) { 
     double sum = 0; 
     for(final Double x : xs) { 
     sum += x; 
     } 
     return sum/xs.size(); 
    } 
    }; 

    public static Function1<List<Double>, Double> max = new Function1<List<Double>, Double>() { 
    public Double apply(final List<Double> xs) { 
     double mx = xs.get(0); 
     for(final Double x : xs) { 
     if(x > mx) { 
      mx = x; 
     } 
     } 
     return mx; 
    } 
    }; 

    public static void main(final String[] args) { 
    final List<Double> myArray = Arrays.asList(3.0, 8, 1, 2, 9); 
    List<Function1<List<Double>, Double>> funcs = new ArrayList<Function1<List<Double>, Double>>(); 
    funcs = addFunc(min, funcs); 
    final List<Function1<List<Double>, Double>> funcs1 = addFunc(max, funcs); 
    final List<Double> answers = applyAllFuncs(funcs1, myArray); 
    final List<Function1<List<Double>, Double>> funcs2 = addFunc(avg, funcs); 
    final List<Double> answers2 = applyAllFuncs(funcs2, myArray); 
    System.out.println(answers + "\n" + answers2); 
    } 
} 

如果使用已經存在的函數式編程庫,用於Java的許多這樣的樣板可以被避免的,比如Functional Java或這是由GridGain提供的。

沒有太多的東西被優化掉,因爲JVM從來沒有打算用於這類東西。 Scala是JVM上的一種功能語言,它使用與上述相同的方法來實現lambdas和更高階的函數,並且提供與Java同等的性能。不過,我建議您應該剖析代碼並確定它是否滿足您特定用例的性能要求。

+1

只是踢,這是等效代碼在Scala中的樣子:http://ideone.com/Fyokg – missingfaktor 2011-04-09 09:39:54