[英]What is Java equivalent of C# default(T)
我目前正在為我的一個項目進行通用 Sum 投影。 代碼就像,
public class Sum<T,U extends Number> implements IProject<T,U,U>
{
@Override
public U eval(Iterable<T> tList, Function<T,U> property)
{
U total;
for (T t : tList)
{
total += property.apply(t);
}
return total;
}
}
但是這里有一個小故障,因為我需要初始化總數(顯然是 0)。 但是無論如何在Java中做它就像在C#中我可以使用default(U)
。
Java 相當於 C# 的default(T)
是null
,這顯然不適用於您的情況,因為您第一次嘗試將某些內容添加到總數時會得到 NullPointerException 。
為了初始化您的總數,您需要在 Java 中使用工廠方法,但它仍然無法正常工作,因為:
+=
。java.lang.Number
是不可變的,因此您不能向其中添加任何內容。你有兩個選擇。
大規模過度設計的方法:
定義一個名為MyNumber
的新接口,其中包含一個add
方法,並編寫相關的非不可變數字類來實現該接口,因此您的代碼將如下所示:
@Override
public <T extends MyNumber> T add( T total, Iterable<T> myNumbers )
{
for( T myNumber : myNumbers )
total.add( myNumber );
return total;
}
(您還需要編寫一個工廠,以便您可以創建一個實例來保存您的總數,而無需確切知道它是什么類型。)
務實的方法:
編寫像這樣的級聯if
語句:
if( number instanceof Integer )
{
//declare int total
//loop to sum integers
//box the total into a Number
}
else if( number instanceof Long )
{
//declare long total
//loop to sum longs
//box the total into a Number
}
...
無論如何, 泛型只存在於引用類型中,因此這將始終為null
。 似乎還有一個隱含的假設,即 + 運算符是為U
定義的 - 您確定對U
可以是什么沒有更多限制嗎? 你也看過做Stream.map
然后是Stream.reduce
嗎? (我假設您使用的是 Java 8,因為您有Function
)
編輯我認為你正在尋找的是幺半群模式。 它在 Java 中不存在,但您可以自己定義它-
interface Monoid<T>
{
T getZero();
T add(T left, T right);
}
因此你的例子會變成
public U eval(Iterable<T> tList, Function<T,U> property, Monoid<U> m)
{
U initial = m.getZero();
return StreamSupport.stream(tList.spliterator(), false)
.map(property)
.reduce(initial, (uLeft, uRight) -> m.add(uLeft, uRight));
}
但這需要更改eval
的簽名,這可能是不可能的,因為我看到它被注釋為@Override
。
這種方法可以擴展到帶有連接的列表和字符串、帶有聯合的集合和映射,其中值本身是一個幺半群,“添加”給定鍵的所有值,以及組合下的函數,其中“零”是恆等函數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.