3 回答

TA貢獻1828條經驗 獲得超13個贊
試試這個奇怪的把戲:
g = oa -> Math.max(0, f.apply(oa.map(a -> a))); // ^----------^
像這樣映射可選類型的類型,可使編譯器將“可選”的類型“轉換”為一致的類型。
這確實存在創建新Optional
實例的缺點。
但是,當然,我問了一個問題,它在思考這是否實際上是規范所允許的東西或錯誤。
就個人而言,我認為您的“迄今為止最好的”并不特別糟糕。當然,這取決于實際代碼的外觀。

TA貢獻1780條經驗 獲得超5個贊
總的來說,我發現Java中超界的類型推斷是一個噩夢。.有很多編譯器錯誤,通常很難推理為什么編譯器會拒絕某種語法而不拒絕其他語法。
就是說,您可以通過強制轉換f為Func<Double>類型來解決這種問題。這并不是完全安全的方法。如果f具有任何狀態,我們可以假設其下限f是Double在現實中可能是Number或Object。使用強制轉換,您不會招致@AndyTurner提供的解決方案的性能損失,但是未經檢查的強制轉換也不是您的朋友。
public double compute(Func<? super Double> f) {
// Sometimes amend the function to do something slightly different
Func<? super Double> g = f;
if (someCondition())
g = oa -> Math.max(0, (((Func<Double>) f)).apply(oa));
return g.apply(Optional.of(3.14)) + g.apply(Optional.empty());
}
總而言之,我認為您在問題中提出的解決方案是解決該問題的最佳解決方案。它有些冗長,但是編譯器應該能夠優化代碼。您不會因未經檢查的強制轉換而失去編譯時的安全性,并且不會由于創建其他Optional實例而導致運行時性能下降。

TA貢獻1811條經驗 獲得超5個贊
解決方案是更改您的接口簽名:
double apply(Optional<? extends A> a);
分析
考慮一下您的界面是否僅僅是:
double apply(A a);
這樣就永遠不會發生錯誤。
這是因為Double
可分配給Object
。編譯器將自動調整類型。這意味著該接口實際上是:
double apply(? extends A a);
因此,您需要做的就是讓您的界面具有這種適應能力。
func(Number)
可以接受Double
作為參數。
func(Optional<Number>)
也應該接受Optional<Double>
。
因此,您應該? extends
在您的界面上添加。
添加回答
舉報