4

I'm writing a function to sum two arrays (of not necessarily equal size) in Java and return the result.

Here's my attempt:

 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; } 

But I have several observations notwithstanding the compile errors.

  1. Why isn't this function in the Java library, which is gigantic in the extreme?

  2. I was motivated to use generics, as you would use templates in C++.

  3. I'm worried about getting deep copies of the input data; lhs and ``rhs. Can anyone reassure me on this? C++ allows me to pass a constant reference; and I'll know for sure.

  4. Instantiation of T[] out appears to be illegal with a generic type. What am I missing?

  5. Will the compiler optimise out my repeated Math.max(lhs.length, rhs.length)?

  6. Compiler doesn't like lhs[i] + rhs[i]. Presumably because it doesn't know the type of T, but C++ allows you do to this as it will not attempt to compile a template until it knows the type.

  7. Are going to take a deep copy of out when returning? Again, C++ compilers would not take an extra copy.

Perhaps I'm too old to get used to Java;-)

4
  • Ad 3) javadude.com/articles/passbyvalue.htm Commented Jul 1, 2013 at 10:14
  • Adding the contents of two arrays of uneven length is not eactly a common activity, i've never done it. If it was then what about dividing two arrays, subtracting two arrays, raising one entry from one array to the power of the other etc etc etc. Java gives you the tools to do it if you need it Commented Jul 1, 2013 at 10:15
  • 1
    T is unknown at runtime which is why you can't do new T[] Commented Jul 1, 2013 at 10:15
  • 4
    And + is only available for primatives (and strings) not all objects so given that you've declared this function as being prepared to take anything the compiler can't let you use + Commented Jul 1, 2013 at 10:16

2 Answers 2

9

1) Why isn't this function in the extremely gigantic Java library?

Asking for opinion, off-topic here.

3) I'm worried about getting deep copies of the input data; lhs and rhs. Can anyone reassure me on this? C++ allows me to pass a constant reference; and I'll know for sure.

7) Are going to take a deep copy of out when returning? Again, C++ compilers would not take an extra copy.

No deep copying is ever done automatically in Java. Furthermore, deep copying is an ill-defined problem in general.

4) Instantiation of T[] out appears to be illegal with a generic type. What am I missing?

Apart from it being impossible to instantiate an array of generic type, generic types only cover reference types. You are quite probably interested only in primitive types here, so they are of no use.

5) Will the compiler optimise out my repeated Math.max(lhs.length, rhs.length)?

Some JITs might, but you can't have any kind of guarantee. Extract to a local variable.

6) Compiler doesn't like lhs[i] + rhs[i]. Presumably because it doesn't know the type of T, but C++ allows you do to this as it will not attempt to compile a template until it knows the type.

Unfortunately, you are in a lot of trouble here. There is no way to generify algorithms to all primitive Java types.

Sign up to request clarification or add additional context in comments.

7 Comments

Hum, but +1. It's not to be construed as a criticism as Java owes its elegance in its considering how to improve other languages, but the above would have all been easily accomplished in C++ using templates. I guess I should build a version using double in place of T.
@Bathsheba In C++ what happens if you try to (for example) add a basketball to annother basketball? As written your code allows this (if the compiler didn't object)
C++ templates are instantiated at compile time with specific types, so they have precious little to do with Java Generics. Yes, JG is quite a limp feature of Java, having a terrible thrust-to-weight ratio, and has already received a lot of criticism to that effect.
@Richard Tingle; in C++ you can overload operators if the operation is meaningful, or allow (or even force) a compile-time error if it's not.
@Bathsheba However the signature of this states explicely that it will take anything (like an arraylist will take anything), it would in fact not be a compile time error but a runtime exception (nasty). It would be nice if you could say anything that is a primative (and with objects you can do this with <? extends ParentClass) but not with primatives. Primatives are only really in java at all because they are admittedly faster than their Object brothers (Integer, Double etc vs int, double etc). As such primatives are very much second class citizens in java
|
1

6) Compiler doesn't like lhs[i] + rhs[i]. Presumably because it doesn't know the type of T, but C++ allows you do to this as it will not attempt to compile a template until it knows the type.

You could always write an interface with an .add(...) function and let T extend this interface. Then you could write lhs[i].add(rhs[i])

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.