The Arrays Class – Collections: Part II
By Jaime Williams / September 23, 2023 / No Comments / Composing Stream Pipelines, Executing Stream Pipelines, Oracle Certification Exam
15.12 The Arrays Class
In this section we look at some selected utility methods from the java.util.Arrays class, in particular, for sorting, searching, and comparing arrays.
Creating list views of arrays using the Arrays.asList() method is covered in §12.7, p. 660, and can be compared with unmodifiable lists created using the factory methods List.of() and List.copyOf().
Using the overloaded static method Arrays.stream() to create streams with arrays as the data source is covered in §16.4, p. 898.
The utility methods declared in the Arrays class are all public and static. Therefore, these two modifiers will be omitted in their method header declarations in this section.
Sorting Arrays
Sorting implies ordering the elements according to some ranking criteria, usually based on the values of the elements. The values of numeric data types are compared and ranked by using the relational operators that define the numerical order of the values. Objects are typically compared according to their natural ordering defined by their class. The class implements the compareTo() method of the Comparable<E> interface. The ordering defined by this method is called the natural ordering for the objects of the class, where obj1.compareTo(obj2) returns the following result:
- A positive value if obj1 is greater than obj2
- The value 0 if obj1 is equal to obj2
- A negative value if obj1 is less than obj2
The wrapper classes for primitive values and the String class implement the compareTo() method (§8.3, p. 432), thereby giving their objects a natural ordering. Arrays with objects of these classes can readily be sorted as the sort algorithm can take advantage of their natural ordering.
The Arrays class provides enough overloaded versions of the sort() method to sort practically any type of array. The discussion on sorting lists (p. 858) is also applicable to sorting arrays.
void sort(
type
[] array)
void sort(
type
[] array, int fromIndex, int toIndex)
The permitted type for elements includes byte, char, double, float, int, long, short, and Object.
These methods sort the elements in the array according to their natural ordering.
In the case of an array of objects being passed as an argument, the objects must be mutually comparable according to the natural ordering defined by the Comparable<E> interface; that is, it should be possible to compare any two objects in the array according to their natural ordering without throwing a ClassCast-Exception.
<E> void sort(E[] array, Comparator<? super E> cmp)
<E> void sort(E[] array, int fromIndex, int toIndex,
Comparator<? super E> cmp)
These two generic methods sort the array according to the total ordering dictated by the comparator. In particular, the methods require that the elements are mutually comparable according to this comparator.
The subarray bounds, if specified in the methods above, define a half-open interval. Only elements in this interval are then sorted.
The Arrays class also defines analogous methods with the name parallelSort for sorting the elements in parallel.
The experiment with a list of strings (p. 858) is repeated in the following with an array of strings, giving identical results. An array of strings is sorted according to different criteria.
String[] strArray = {“biggest”, “big”, “bigger”, “Bigfoot”};
Arrays.sort(strArray); // Natural order
Arrays.sort(strArray, Comparator.comparing(String::length)); // Length order
Arrays.sort(strArray, Collections.reverseOrder()); // Reverse natural order
Arrays.sort(strArray, String.CASE_INSENSITIVE_ORDER);// Case insensitive order
Arrays.sort(strArray, // Reverse case insensitive order
Collections.reverseOrder(String.CASE_INSENSITIVE_ORDER));
The output below shows the array before sorting, followed by the results from the calls to the Arrays.sort() methods above, respectively:
Before sorting: [biggest, big, bigger, Bigfoot]
After sorting in natural order: [Bigfoot, big, bigger, biggest]
After sorting in length order: [big, bigger, Bigfoot, biggest]
After sorting in reverse natural order: [biggest, bigger, big, Bigfoot]
After sorting in case insensitive order: [big, Bigfoot, bigger, biggest]
After sorting in reverse case insensitive order: [biggest, bigger, Bigfoot, big]
The examples below illustrate sorting an array of primitive values (int) at (1), an array of type Object containing mutually comparable elements (String) at (2), and a half-open interval in reverse natural ordering at (3). A ClassCastException is thrown when the elements are not mutually comparable, at (4) and (5).
int[] intArray = {5, 3, 7, 1}; // int
Arrays.sort(intArray); // (1) Natural order: [1, 3, 5, 7]
Object[] objArray1 = {“I”, “am”, “OK”}; // String
Arrays.sort(objArray1); // (2) Natural order: [I, OK, am]
Comparable<Integer>[] comps = new Integer[] {5, 3, 7, 1}; // Integer
Arrays.sort(comps, 1, 4, Collections.reverseOrder());// (3) Reverse natural order:
// [5, 7, 3, 1]
Object[] objArray2 = {23, 3.14, “ten”}; // Not mutually comparable
// Arrays.sort(objArray2); // (4) ClassCastException
Number[] numbers = {23, 3.14, 10L}; // Not mutually comparable
// Arrays.sort(numbers); // (5) ClassCastException