2014-11-05 49 views
2

爲了只使用來自java.util.function的預定義函數接口,我開始想知道爲什麼不能在類型聲明中指定可變參數。例如,我想提供的API,它可以像這樣可變內部類型聲明的規範

object.method((x, y, z) -> x + y - z) 

method需要的n個參數數學函數來使用。以下是我希望我的object界面看起來像

interface I { 
    I method(ToDoubleFunction<double...> f); 
} 

我不知道我可以定義自己的funcional接口,或更改API略指定double[]尖括號。我很好奇,爲什麼上面提到的做法是不可行的。

編輯:

在評論中有一個解釋,爲什麼上面的例子不是可變參數的正確用法。 Radiodef分我quesion成兩個分開的人

  1. 爲什麼可變參數不允許作爲一個一般的參數和
  2. 爲什麼你不能在Java中的名字聲明和訪問可變參數。

由於問題的標題,我必須堅持第一個問題。這裏是預期的行爲:

ToDoubleFunction<double...> lambda = (double... d) -> d[0] + d[1] - d[2]; 
lambda.applyAsDouble(1, 2, 3); 
+1

您可以給出一個有用的例子,說明'方法'在這種情況下會做什麼,不知道函數的arity是否仍然會導致有用的操作? – 2014-11-05 18:41:27

+0

Java可變參數不能以這種方式工作'(x,y,z) - > x + y - z'。參數作爲一個數組傳遞,所以你想要做的是按名稱訪問數組索引,可變參數可以使用任意數量的索引來獲取數組。 – Radiodef 2014-11-05 18:45:10

+2

也許值得注意的是,我不認爲你真正想要的是變量arity,而是對n元組的隱式支持。元組更有用,因爲元組仍然是內置的類型。不幸的是,Java不支持元組。 – 2014-11-05 18:55:52

回答

3

聲明的方法參數作爲可變參數意味着呼叫者可以提供的參數其中接收機將處理像陣列的任意數量。

因此,它是爲實現您是否寫沒有區別:

static double f(double... a) { return a[0]+a[1]-a[2]; } 

static double f(double[] a) { return a[0]+a[1]-a[2]; } 

所以寫下來lambda表達式,這實現的功能,這是無關緊要是否一個參數被指定爲可變參數,特別是因爲您可以省略參數類型,因此沒有人會看到是否隱含[]...

所以,當你拒絕使用自己的界面,你將不得不寫下來

ToDoubleFunction<double[]> f=a->a[0]+a[1]-a[2]; 

,當然,要記住,你的代碼假設某個數組的長度。

在一名助手的界面,事情可能會更容易:

interface F3 extends ToDoubleFunction<double[]> { 
    double apply(double a0, double a1, double a2); 
    default double applyAsDouble(double[] a) { 
     return apply(a[0], a[1], a[2]); 
    } 
} 

,那麼你可以這樣寫:

ToDoubleFunction<double[]> f=(F3)(x,y,z)->x+y-z; 

類似的事情會用等效F4接口等工作,並且你可以將它們全部處理爲ToDoubleFunction<double[]>,但當你將代碼與數組長度不同的假設混合在一起時,編譯器不會警告你(當你假設一個不太可變的arity時,與可變參數相同的問題)。

調用數組期待不聲明參數作爲變量參數可以隨時與確實想到一個輔助方法包裹方法可變參數:

static double apply(ToDoubleFunction<double[]> f, double... arg) { 
    return f.applyAsDouble(arg); 
} 

你可以評估你的功能這樣的方法簡單如apply(f, 1, 2, 3)

我有沒有提到編譯器不會在參數個數不匹配時發出警告?