[英]What is Java equivalent of C# default(T)
I'm currently working on generic Sum projection for one of my projects.我目前正在为我的一个项目进行通用 Sum 投影。 The code is like,代码就像,
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;
}
}
However there is a little glitch here since I need to initialize the total (obviously to 0).但是这里有一个小故障,因为我需要初始化总数(显然是 0)。 But is there anyway to do it in java like in C# I could use default(U)
.但是无论如何在Java中做它就像在C#中我可以使用default(U)
。
Java's equivalent to C#'s default(T)
is null
, which clearly would not work in your case, because you would get a NullPointerException the first time you tried to add something to your total. Java 相当于 C# 的default(T)
是null
,这显然不适用于您的情况,因为您第一次尝试将某些内容添加到总数时会得到 NullPointerException 。
In order to initialize your total you would need a factory method in java, but it still would not work, because:为了初始化您的总数,您需要在 Java 中使用工厂方法,但它仍然无法正常工作,因为:
+=
on generics in java.你不能在 java 中的泛型上使用+=
。java.lang.Number
is immutable, so you cannot add anything to it. java.lang.Number
是不可变的,因此您不能向其中添加任何内容。You have two options.你有两个选择。
The massively overengineered approach:大规模过度设计的方法:
Define a new interface called, say, MyNumber
which contains an add
method, and write associated non-immutable numeric classes implementing this interface, so your code would then look like this:定义一个名为MyNumber
的新接口,其中包含一个add
方法,并编写相关的非不可变数字类来实现该接口,因此您的代码将如下所示:
@Override
public <T extends MyNumber> T add( T total, Iterable<T> myNumbers )
{
for( T myNumber : myNumbers )
total.add( myNumber );
return total;
}
(You would also need to write a factory so that you can create an instance to hold your total without knowing precisely what type it is.) (您还需要编写一个工厂,以便您可以创建一个实例来保存您的总数,而无需确切知道它是什么类型。)
The pragmatic approach:务实的方法:
Write cascaded if
statements like this:编写像这样的级联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
}
...
Generics only exist for reference types anyway , so this would always be null
. 无论如何, 泛型只存在于引用类型中,因此这将始终为null
。 There also seems to be an implicit assumption that the + operator is defined for U
- are you sure there aren't more constraints on what U
can be?似乎还有一个隐含的假设,即 + 运算符是为U
定义的 - 您确定对U
可以是什么没有更多限制吗? Also have you looked at doing Stream.map
followed by Stream.reduce
?你也看过做Stream.map
然后是Stream.reduce
吗? (I assume you are using Java 8 as you have Function
) (我假设您使用的是 Java 8,因为您有Function
)
EDIT I think what you are looking for is the monoid pattern.编辑我认为你正在寻找的是幺半群模式。 It doesn't exist in Java but you can define it yourself -它在 Java 中不存在,但您可以自己定义它-
interface Monoid<T>
{
T getZero();
T add(T left, T right);
}
And thus your example would become因此你的例子会变成
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));
}
but that would require changing the signature of eval
, which might not be possible as I see it's annotated @Override
.但这需要更改eval
的签名,这可能是不可能的,因为我看到它被注释为@Override
。
This approach is extensible to Lists and Strings with Concatenation, Sets with union and Maps where the value is itself a monoid, "adding" all values of a given key, and functions under composition where the "zero" is the identity function.这种方法可以扩展到带有连接的列表和字符串、带有联合的集合和映射,其中值本身是一个幺半群,“添加”给定键的所有值,以及组合下的函数,其中“零”是恒等函数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.