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库中没有这个功能,这个功能非常巨大?

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

  3. 我担心获取输入数据的深层副本;lhs和`rhs。任何人都可以让我放心吗?C++ 允许我传递一个常量引用;我肯定会知道的。

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

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

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

  7. 回来的时候会拿出深拷贝吗?同样,C++ 编译器不会额外复制一份。

也许我太老了,无法习惯 Java;-)

4

2 回答 2

9

1)为什么在极其庞大的Java库中没有这个功能?

征求意见,这里跑题了。

3)我担心得到输入数据的深层副本;左手和右手。任何人都可以让我放心吗?C++ 允许我传递一个常量引用;我肯定会知道的。

7) 回来的时候要拿出深拷贝吗?同样,C++ 编译器不会额外复制一份。

在 Java 中不会自动进行深度复制。此外,深度复制通常是一个定义不明确的问题。

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

除了不可能实例化泛型类型的数组之外,泛型类型仅涵盖引用类型。你很可能只对这里的原始类型感兴趣,所以它们没有用。

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

一些 JIT 可能会,但你不能有任何保证。提取到局部变量。

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

不幸的是,你在这里遇到了很多麻烦。没有办法将算法推广到所有原始 Java 类型。

于 2013-07-01T10:18:06.140 回答
1

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

你总是可以用 .add(...) 函数编写一个接口,并让 T 扩展这个接口。然后你可以写 lhs[i].add(rhs[i])

于 2013-07-01T11:22:01.347 回答