簡體   English   中英

什么是 C# default(T) 的 Java 等價物

[英]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 中使用工廠方法,但它仍然無法正常工作,因為:

  1. 你不能在 java 中的泛型上使用+=
  2. 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM