Why is autoboxing not allowed for primitive arrays when using Arrays.sort()?

608 views Asked by At

It is known that autoboxing can be computationally intensive, but it seems to me that allowing primitive arrays be autoboxed to their Object equivalent for sorting methods is an appropriate edge case, particularly when the values are being sorted based on some external calculation.

I had an issue earlier, where a given array of primitive ints needed to be sorted by the results of a calculation based on the index value. However,java.util.Comparator does not allow primitive types for any implementing classes and compare(T x, T y) methods.

So instead of doing something like

public void sortRow(int row){
  Arrays.sort(this.buffer[row], new Comparator<Integer>(){  
    @Override
    public int compare(int x, int y){
      return (PhotoUtils.getBrightnessValue(x) <= PhotoUtils.getBrightnessValue(y) ? x : y;
    }
  }
}

I had to implement a second step:

public void sortRow(int row){
  Integer[] tempArray = new Integer[this.buffer[row].length];

  for (int i = 0; i < tempArray.length; i++)
    tempArray[i] = this.buffer[row][i];

  Arrays.sort(tempArray, new Comparator<Integer>(){  
    @Override
    public int compare(Integer x, Integer y){
      return (PhotoUtils.getBrightnessValue(x) <= PhotoUtils.getBrightnessValue(y) ? x : y;
    }
  }
}
3

There are 3 answers

0
rgettman On BEST ANSWER

According to the JLS, Section 5.1.7, there are only the following specified boxing conversions, and arrays aren't involved in any of them:

Boxing conversion converts expressions of primitive type to corresponding expressions of reference type. Specifically, the following nine conversions are called the boxing conversions:

  • From type boolean to type Boolean

  • From type byte to type Byte

  • From type short to type Short

  • From type char to type Character

  • From type int to type Integer

  • From type long to type Long

  • From type float to type Float

  • From type double to type Double

  • From the null type to the null type

1
AudioBubble On

To Autobox a single value requires an allocation of a new primitive wrapper object. To autobox an entire array would require allocation of new primitve wrapper objects for each element of the array, as well as allocation of a new Array of references to hold the references to the new objects you just created. So it would be a lot of overhead for something that is done implicitly by a cast. What this means is that if you have a variable of type byte[] with size of say 1024, then you would have to allocate an array of references which are each 4-8 bytes. and allocate each of the 1024 Byte objects to fill with the values from your original array. thus you are now allocating at least 5120-9216 bytes of data in addition to the 1024 originally added to the array.

3
Sotirios Delimanolis On

I think the issue here is more that Type arguments can only be reference types or wildcards. From the JLS Section 4.5.1

Type arguments may be either reference types or wildcards.

The Arrays.sort(E, Comparator<? super E>) method is a generic method where the type variable E is bound to the type argument used for both the array and the Comparator, ie. they must be the same. Primitives cannot be used with generics and therefore you cannot use arrays of primitive types.

Why is autoboxing not allowed for primitive arrays when using Arrays.sort()?

So the problem with Arrays.sort isn't autoboxing, it's a limitation of Generics.

For why autoboxing doesn't apply to primitives, see the other answers. Basically the JLS doesn't allow it.