繁体   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