【问题标题】:Arithmetic element by element difference between 2 collections using Java Generics使用Java泛型的2个集合之间的算术元素逐元素差异
【发布时间】:2012-12-25 22:42:33
【问题描述】:

假设我们有 2 个有序的数字集合。我们要逐个元素地计算算术差异。 我认为我们需要使用数字列表来模拟“有序数字集合”的概念。 问题是没有为 Number 定义算术差异(如 3-2 中的平庸的“-”)。 我可以将所有内容都转换为 Double,但我更喜欢干净的解决方案。

public static <E extends Number> List<E> listDifferenceElementByElement(List<E> minuend, List<E> subtrahend) throws Exception {
    if (minuend.size() != subtrahend.size()) {
        throw new Exception("Collections must have the same size"); //TODO: better exception handling
    }
    List<E> difference = new ArrayList<E>();
    int i = 0;
    for (E currMinuend : minuend) {
        difference.add(currMinuend-subtrahend.get(i)); //error: The operator - is undefined for the argument type(s) E, E
        i++;
    }
    return difference;
}

有什么想法吗?

【问题讨论】:

  • 为什么需要泛型类型?如果您将 E 改为 Double 会怎样?
  • 假设我想要一些可以与任何数字类型(整数、浮点数、双精度...)一起使用并可能返回相同类型的东西
  • 作为一个练习,你不能用简单的方式来做。实际上,它非常有用,因为如果您拥有这样的功能,将不会有太多收获。如果您关心性能,您可以改用long[]double[]。这是数学库中通常使用的。

标签: java list generics collections array-difference


【解决方案1】:

由于Number 没有提供任何subtract 方法,你不能简单地做到这一点。我能想到的替代方案是:

  1. 使用提供的 doubleValue() 方法,并返回 double,但如果列表包含 BigDecimal,则可能会丢失精度。
  2. 每个可用的Number 子类有一个方法,但它可能会创建大量重复代码...
  3. 将类型限制为任何有意义的类型(如果精度无关紧要,则说 double 或 BigDecimal),这是 (2) 的子情况。

选项 2 可以通过将 difference.add(currMinuend-subtrahend.get(i)); 替换为 difference.add(subtract(currMinuend, subtrahend.get(i))); 来实现

那么只需要写10个subtract方法:

private static int subtract(int a, int b) { return a - b; }
private static double subtract(double a, double b) { return a - b; }
private static BigDecimal subtract(BigDecimal a, BigDecimal b) { return a.subtract(b); }

等等

【讨论】:

  • BigDecimal 是去这里的方式
  • @AndersR.Bystrup 这确实是一种方法。
  • 我以某种方式想到了相同的可能策略,但我认为可能有更好的解决方案。想象一下,我可以在运行时检查 minuend 中元素的类型:如果它们是 Integer 或 Double 左右,我可以使用算术运算符“-”并返回一组 Integer 或 Double 左右。对吗?
  • @Paolo 你可以这样做,最终归结为第二种选择:每种类型一个方法。
  • @Anders R. Bystrup 和 assylias 是的,我会这样做,每种类型一个方法。顺便说一句,在 Python 中我会更容易做到(当我第一次从 Java 迁移到 Python 时,我总是说我会在 Java 中更容易地做到这一点。现在我搬回去了,我说的是相反的......哈哈!!)
【解决方案2】:

如果您想使用多种算术类型,您可以将您的列表设置为通用列表,然后在您想找到它们之间的差异时添加处理程序。处理程序检查类型是否为 Double、Integer 或任何您想要的实例。您可以根据每种类型计算差异。

【讨论】:

    【解决方案3】:

    这与泛型、数组等无关。Java 不允许运算符重载,因此您不能用- 减去2 个数字,并且Number 类没有定义任何数字运算方法。不能,因为它可能在不同的子类上运行(例如 Integer.subtract(Double)),这会使定义返回类型变得不可能。

    我想你需要在这里使用内在类型或BigDecimal(或类似的)。

    【讨论】:

      猜你喜欢
      • 2023-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-21
      相关资源
      最近更新 更多