如何在Java中对数组求和

4
我正在编写一个Java函数,用于对两个数组(大小不一定相等)求和并返回结果。
以下是我的尝试:
 public static <T> T[] sumArrays(T[] lhs, T[] rhs)
    {
        T[] out = new T[Math.max(lhs.length, rhs.length)];

        for (int i = 0; i < Math.max(lhs.length, rhs.length); ++i){            
            if (i < Math.min(lhs.length, rhs.length)){
                out[i] = lhs[i] + rhs[i];                
            } else if (i < lhs.length){
                out[i] = lhs[i];
            } else /* if (i < rhs.length)*/{
                out[i] = rhs[i];
            }            
        }
        return out;        
    }

尽管编译错误,但我有一些观察。

  1. 为什么这个函数不在Java库中呢?Java库非常庞大。

  2. 我被激励使用泛型,就像你在C++中使用模板一样。

  3. 我担心会得到输入数据的深度拷贝;lhs和rhs。有人能让我放心吗?C++允许我传递一个常量引用;我会确定的。

  4. 使用泛型类型似乎是非法的,T[]实例化时出现了问题。我错过了什么?

  5. 编译器会优化我的重复代码Math.max(lhs.length, rhs.length)吗?

  6. 编译器不喜欢lhs[i] + rhs[i]。可能是因为它不知道T的类型,但是C++允许你这样做,因为它不会试图在知道类型之前编译模板。

  7. 在返回时,是否要对out进行深层复制?同样,C++编译器不会多进行一次复制。

也许我太老了,无法适应Java;-)


广告3)http://javadude.com/articles/passbyvalue.htm - Anders R. Bystrup
将两个长度不同的数组的内容相加并不是一项常见的活动,我从未这样做过。如果需要进行此类操作,那么除了相加之外,还可以进行除法、减法、将一个数组中的一个条目提高到另一个数组的幂等等。Java为您提供了必要的工具,以便在需要时进行这些操作。 - Richard Tingle
1
在运行时,T 是未知的,这就是为什么你不能使用 new T[] 的原因。 - blank
4
“+”操作符仅适用于原始数据类型(以及字符串),而不是所有对象。因此,考虑到您已将此函数声明为可接受任何类型的输入,编译器无法让您使用“+”操作符。 - Richard Tingle
2个回答

9

1) 为什么这个函数不在Java库中?

询问意见,与主题无关。

3) 我担心会得到输入数据lhs和rhs的深拷贝。有人能向我保证吗?C++允许我传递常量引用;这样我就可以确定了。

7) 返回时会对out进行深层复制吗?同样,C++编译器不会多做一次拷贝。

在Java中,不会自动进行深度复制。此外,在一般情况下,深度复制是一个不清晰的问题。

4) 泛型类型 T[] 的实例化似乎是非法的。我错过了什么?

除了无法实例化通用类型数组之外,通用类型仅涵盖引用类型。在这里,您很可能只对原始类型感兴趣,所以它们没有用处。

5) 编译器会优化我的重复代码Math.max(lhs.length, rhs.length)吗?

一些JIT可能会,但您无法获得任何保证。请将其提取到本地变量中。

6) 编译器不喜欢lhs[i] + rhs[i]。这可能是因为它不知道T的类型,但是C++允许您这样做,因为它不会尝试在知道类型之前编译模板。

不幸的是,在这里,您会遇到很多麻烦。没有办法将算法泛化到Java的所有原始类型中。


嗯,但是+1。这并不是批评Java的优雅之处在于它考虑如何改进其他语言,但是上述内容在C++中使用模板很容易实现。我想我应该构建一个版本,使用double代替T。 - Bathsheba
@Bathsheba 在C++中,如果您尝试将一个篮球添加到另一个篮球中会发生什么?按照您的代码编写方式,允许这种操作(如果编译器不反对)。 - Richard Tingle
2
C++ 模板在编译时使用特定类型进行实例化,因此它们与 Java 泛型几乎没有任何关系。是的,Java 的泛型功能相当弱,具有可怕的推力重量比,并已经受到了很多批评。 - Marko Topolnik
1
@Richard Tingle;在C++中,如果操作有意义,您可以重载运算符,或者允许(甚至强制)在编译时出现错误。 - Bathsheba
@Bathsheba 我承认,我经常想编写一个函数,它可以接受浮点或双精度参数,并返回浮点或双精度,这样我就可以在不需要进行大量从一种类型到另一种类型的困难迁移的情况下从浮点精度和双精度程序之间进行切换。这是 Java 中确实缺少的东西。 - Richard Tingle
显示剩余2条评论

1

6) 编译器不喜欢 lhs[i] + rhs[i]。可能是因为它不知道 T 的类型,但是 C++ 允许你这样做,因为它在不知道类型之前不会尝试编译模板。

你可以编写一个带有 .add(...) 函数的接口,并让 T 扩展此接口。然后你可以写 lhs[i].add(rhs[i])。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接