[英]Java: Generic methods and numbers
我想制作一个通用方法,它可以得到一个数字List
的总和。
我在想的是这个:
public static <T extends Number> T sumList(List<T> data)
{
T total = 0;
for (T elem : data)
{
total += elem;
}
return total;
}
但问题是there is no += operator in T
并且total can't be assigned to zero
。
我怎样才能做到这一点?
谢谢
有一些方法你可以一起破解这个,但老实说,仿制药根本不是去这里的方式。 为每个具体的原始包装类型构建一个方法并分别实现它们。 使它成为通用的将是一件令人头疼的问题; 算术运算一般不会发生。
通过使它成为通用的,你也没有真正获得任何东西。 它是如此简单和常量的代码,您不必担心代码重复,因为它不会改变。 人们不会将自己的数字类型传递给您的代码; 它适用的类型域已经很好地定义和有限。
我最近已经完成了(基于lambdaj代码),请注意它需要所有元素都是相同的类型(你不能真正添加一个Byte
和一个BigDecimal
)并且如果不是这样的话可以抛出一个CCE不会处理自定义Number
:
public class SumAggregator<T extends Number> {
public T aggregate(Iterable<T> iterable) {
T result = null;
for (T item : iterable) {
result = aggregate(result, item);
}
return result;
}
@SuppressWarnings("unchecked")
protected T aggregate(T first, T second) {
if (first == null) {
return second;
} else if (second == null) {
return first;
} else if (first instanceof BigDecimal) {
return (T) aggregate((BigDecimal) first, (BigDecimal) second);
} else if (second instanceof BigInteger) {
return (T) aggregate((BigInteger) first, (BigInteger) second);
} else if (first instanceof Byte) {
return (T) aggregate((Byte) first, (Byte) second);
} else if (first instanceof Double) {
return (T) aggregate((Double) first, (Double) second);
} else if (first instanceof Float) {
return (T) aggregate((Float) first, (Float) second);
} else if (first instanceof Integer) {
return (T) aggregate((Integer) first, (Integer) second);
} else if (first instanceof Long) {
return (T) aggregate((Long) first, (Long) second);
} else if (first instanceof Short) {
return (T) aggregate((Short) first, (Short) second);
} else {
throw new UnsupportedOperationException("SumAggregator only supports official subclasses of Number");
}
}
private BigDecimal aggregate(BigDecimal first, BigDecimal second) {
return first.add(second);
}
private BigInteger aggregate(BigInteger first, BigInteger second) {
return first.add(second);
}
private Byte aggregate(Byte first, Byte second) {
return (byte) (first + second);
}
private Double aggregate(Double first, Double second) {
return first + second;
}
private Float aggregate(Float first, Float second) {
return first + second;
}
private Integer aggregate(Integer first, Integer second) {
return first + second;
}
private Long aggregate(Long first, Long second) {
return first + second;
}
private Short aggregate(Short first, Short second) {
return (short) (first + second);
}
}
看看以下用于求和任何Number类型变量列表的泛型方法示例......我确信这就是你要求的......
Mark Peters的答案也是对的,但这也是一个可行的解决方案。
public class GenericSum {
@SuppressWarnings("unchecked")
public static <E> E sumArray(E[] inputArray) {
Double result = 0.0;
// Sum array elements
for (E element : inputArray) {
result = ((Number) result).doubleValue()
+ ((Number) element).doubleValue();
}
return ((E) result);
}
public static void main(String args[]) {
// Create arrays of Integer, Double
Integer[] intArray = { 1, 2, 3, 4, 5 };
Double[] doubleArray = { 1.1, 2.2, 3.3, 4.4 };
System.out.println("Sum of doubles : " + sumArray(intArray));
System.out.println("Sum of doubles : " + sumArray(doubleArray));
}
}
您可以使用库,例如Generic Java Math (其编号部分),它为Number子类提供通用操作。 它提供了一种通常使用数字的方法,就像在您的示例中一样,但是通过传递Arithmetics对象,可以进行实际计算。 请参阅主页上的示例。
它必须使用盒装类型,因此如果您需要速度,在Java中没有通用实现可以做到这一点,您必须使用原始类型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.