gpt4 book ai didi

java - 不同类型的 ArrayList 的总和

转载 作者:搜寻专家 更新时间:2023-11-01 01:16:27 25 4
gpt4 key购买 nike

是否可以写一个方法totalArrayList 的所有元素求和, 它的类型是 <Integer><Long>

我不能只写

public long total(ArrayList<Integer> list) 

public long total(ArrayList<Long> list) 

一起因为会出现删除错误,和Integer不会自动扩展到 Long反之亦然...但里面的代码是相同的!

最佳答案

是的,您可以实现这样的方法,因为 IntegerLong 都扩展了 Number .例如,您可以使用 wildcard type对于列表元素类型:

public static long total(List<? extends Number> list) {
long sum = 0;
for (Number n : list) {
if (!(n instanceof Byte || n instanceof Short || n instanceof Integer || n instanceof Long)) {
throw new IllegalArgumentException();
}
sum += n.longValue();
}
return sum;
}

这只适用于整数类型,因为 sum 变量和返回值是 long 类型。

理想情况下,您还希望能够将该方法与 FloatDouble 一起使用,并返回一个与列表元素类型相同类型的对象,但是这不容易做到,原因有二:

  1. 您可以对Number 做的唯一一件事就是将其值作为原始数字类型之一获取。您不能以依赖于数字的方式对其中两个求和。
  2. 不可能创建正确类的 0 对象。

编辑: 很久以后...

只是为了好玩,让我们以一种适合 Java 的方式来做这件事。你要做的事情就是手动提供上面提到的两个操作。具有两个这样操作的一种值通常称为 monoid在代数和函数式编程的背景下。

这个问题可以通过创建代表幺半群操作的对象来解决:

interface MonoidOps<T> {
T id();
T op(T o1, T o2);
}

现在可以实现 total 方法来获取除列表之外的此类型的对象:

public static <T> T total(List<T> list, MonoidOps<T> ops) {
T sum = ops.id();
for (T e : list) {
sum = ops.op(e, sum);
}
return sum;
}

要为数字类提供 MonoidOps 实现,让我们创建一个简单的辅助类:

class SimpleMonoidOps<T> implements MonoidOps<T> {
private final T idElem;
private final BinaryOperator<T> operation;

public SimpleMonoidOps(T idElem, BinaryOperator<T> operation) {
this.idElem = idElem;
this.operation = operation;
}

public T id() {
return idElem;
}

public T op(T o1, T o2) {
return operation.apply(o1, o2);
}
}

MonoidOps 实现现在可以像这样整齐地编写:

static final MonoidOps<Integer> INT_MONOID_OPS = new SimpleMonoidOps<>(0, Integer::sum);
static final MonoidOps<Double> DOUBLE_MONOID_OPS = new SimpleMonoidOps<>(0.0, Double::sum);

total 方法将这样调用:

int sum = total(Arrays.asList(1, 2, 3), INT_MONOID_OPS);

关于java - 不同类型的 ArrayList 的总和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30763662/

25 4 0