4

The situation is I have a function, and it calls Arrays.sort to sort given array. As Arrays.sort can sort both String and long, I want to use one single signature instead of two String[] array and long[] array.

I've tried something like Comparable[], it won't match long[]. I've also tried change long to Long. But the process of boxing and unboxing is significantly slowing down the sorting.

So I am wondering if there is a type I can specify that matches both of them? Or generally match all supported types of Arrays.sort?

Sraw
  • 18,892
  • 11
  • 54
  • 87
  • The only thing which comes to mind would be to just store your long numbers as `String`. But the problem there is that numbers and text numbers don't sort the same way. Maybe you can add information to your question which explains why you need to do this. – Tim Biegeleisen Nov 01 '18 at 00:33
  • AFAIK there isn't a way to do this--in fact, the JDK itself has a separate overload for each primitive array type for `Arrays.sort`: http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/be44bff34df4/src/share/classes/java/util/Arrays.java – nanofarad Nov 01 '18 at 00:33

2 Answers2

3

The short answer is no, you can't.

Comparable is an interface and part of the object/class-system. A primitive, such as long, is not part of that system, only its boxed variant Long.

Unfortunately, you even can not solve this using generics, since they can also only be applied to classes, not to primitives (see Why don't Java Generics support primitive types?).

So until Project Valhalla (value types) releases, you will need to provide hard-coded variants for all 8 primitives (short, int, long, byte, char, float, double, boolean) if you want to avoid auto-boxing, there is no way around.

The Java API must do this too. You see overloaded methods of Arrays#sort for all relevant primitives and one generic overload for classes. From its documentation:

sort​(byte[] a)
sort​(char[] a)
sort​(double[] a)
sort​(float[] a)
sort​(int[] a)
sort​(long[] a)
sort​(short[] a)
sort​(Object[] a)
sort​(T[] a, Comparator<? super T> c)
Zabuzard
  • 25,064
  • 8
  • 58
  • 82
  • Just cannot believe this is how Java works... I really miss Python for now. – Sraw Nov 01 '18 at 00:36
  • It's due to the nature of how generics are implemented in Java. And unfortunately it was not possible to go a different way without breaking backwards compatibility (which is an important point for Java) back then. – Zabuzard Nov 01 '18 at 00:37
  • Yeah I understand this is a historical problem. Not Java's fault. – Sraw Nov 01 '18 at 00:38
  • It may change once Valhalla is finished though :) – Zabuzard Nov 01 '18 at 00:38
  • I learned Java many years ago and it hasn't improved even a little on this part... It is just the same as that time. – Sraw Nov 01 '18 at 00:47
  • I agree for that specific part of the language. However, there were many other nice additions in the meantime. – Zabuzard Nov 01 '18 at 00:49
0

The situation is I have a function, and it calls Arrays.sort to sort given array. As Arrays.sort can sort both String and long, I want to use one single signature instead of two String[] array and long[] array.

One can try method overloading like this.

public static void main(String [] args) {
    String [] strs = {"c", "x", "a", "d"};
    long [] ints = {4L, 343660L, 99L, 0L};
    Testing t = new Testing();
    t.sortMyArray(strs);
    t.sortMyArray(ints);
    System.out.println(Arrays.toString(strs)); // [a, c, d, x]
    System.out.println(Arrays.toString(ints)); // [0, 4, 99, 343660]
}

private void sortMyArray(long[] myArray) {
    Arrays.sort(myArray);
}

private void sortMyArray(String[] myArray) {
    Arrays.sort(myArray);
}
prasad_
  • 12,755
  • 2
  • 24
  • 36
  • This is exactly what I mean "two signatures". – Sraw Nov 01 '18 at 01:56
  • In Java this is one method signature - and is a case of overloaded methods. – prasad_ Nov 01 '18 at 02:01
  • This is a method with two different signatures. Or specifically, these are two functions with the same name. – Sraw Nov 01 '18 at 02:12
  • In case just two types of arrays a method like this can work, but overloading is preferred: `public void sortMyArray(String [] strs, long [] ints) { // have logic to sort any or both arrays...};` To call such a method: `sortMyArray(strs, ints);` -or-`sortMyArray(null, ints)`; -or- `sortMyArray(strs, null);` etc., it gets tedious. – prasad_ Nov 01 '18 at 02:28