10 minutes read

This topic will cover a useful utility class you can use for array operations. The class is called Arrays. It belongs to the java.util package and provides us with a group of static methods that have various overloads to accept different types. We will look at most of its methods and learn how they work with practical examples.

You may not have studied some topics mentioned here. Don't worry, the topic is completely optional. Moreover paragraphs are independent from each other. If you find some paragraphs tricky, just skip them or return after sometime.

Simple array operations

Let's start our journey with the most basic methods. They are:

  • Arrays.toString()

  • Arrays.equals()

  • Arrays.compare()

The first method is fairly self-explanatory. It is used to convert an array to a String and print the result.

    byte[] arr = { 0, 1, 2, 4, 8, 16, 32, 64 };
    String arrayAsString = Arrays.toString(arr); // [0, 1, 2, 4, 8, 16, 32, 64]

    System.out.println(arrayAsString);

The next two have a similar role, but there are some significant differences between them. The first one checks arrays for equality:

    byte[] arr1 = {1, 2, 3};
    byte[] arr2 = {1, 2, 3};
    byte[] arr3 = {2, 1, 3};

    System.out.println(Arrays.equals(arr1, arr2)); // true
    System.out.println(Arrays.equals(arr2, arr3)); // false

Note that their elements must be in the same order. If your arrays have the same exact elements in a different order, the arrays are not equal.
The third method also performs a check for equality. The difference is that it compares arrays lexicographically.

Lexicographic order is the same as the dictionary order of items.

    byte[] arr1 = {0, 1, 2};
    byte[] arr2 = {1, 2, 3};
    byte[] arr3 = {1, 2, 3};
    byte[] arr4 = {0, 1, 2};

    System.out.println(Arrays.compare(arr1, arr2)); // -1
    System.out.println(Arrays.compare(arr2, arr3)); // 0
    System.out.println(Arrays.compare(arr3, arr4)); // 1

It shows whether the first array passed as an argument is smaller, equal, or greater than the second one. If it is smaller or greater, the output is -1 or 1 accordingly. When the arrays are equal the output is 0.

Copying arrays

This class represents two methods for copying array elements into a new array:

  • Arrays.copyOf()

  • Arrays.copyOfRange()

Arrays.copyOf() takes two arguments: the copied array starting from the first element and the length of the new array. If the value of the second argument is larger than the original array, the missing elements will be filled with zeros.

    byte[] arr1 = {1, 2, 3};
    byte[] arr2 = Arrays.copyOf(arr1, 3);
    byte[] arr3 = Arrays.copyOf(arr1, 4);

    System.out.println(Arrays.toString(arr2)); // [1, 2, 3]
    System.out.println(Arrays.toString(arr3)); // [1, 2, 3, 0]

Arrays.copyOfRange() works in the same way, but here you can specify the element index to copy the array from. This method also fills the array with zeros if the length of the new array is specified as greater than the one being copied:

    byte[] arr1 = {1, 2, 3};
    byte[] arr2 = Arrays.copyOfRange(arr1, 1, 3);
    byte[] arr3 = Arrays.copyOfRange(arr1, 1, 4);

    System.out.println(Arrays.toString(arr2)); // [2, 3]
    System.out.println(Arrays.toString(arr3)); // [2, 3, 0]

In this method, you specify the first element index inclusively and the last element index exclusively.

Sorting arrays and searching

The next pair of important methods are designed for sorting an array and searching for an element. Those methods are:

  • Arrays.sort()

  • Arrays.binarySearch()

We're presenting them together in this section since binarySearch() requires the array to be sorted, otherwise, the result is undefined. So let's start with the sorting method itself.

    byte[] arr = {3, 1, 2};
    Arrays.sort(arr);

    System.out.println(Arrays.toString(arr)); // [1, 2, 3]

With the regular base types, everything is pretty simple, as you can see how in the example above.

When using the sort() method, you can specify the range of elements to be sorted. If you are curious about how it works you are welcome to discover this feature yourself and share the code in the comment!


Now, ask yourself a question: what if we pass not base types but our user-defined classes? By default, the method doesn't know how to sort custom types. In this matter, we must use the Comparator interface.

public class ComparatorDemo {
    public static void main(String[] args) {
        Person[] persons = {new Person(40), new Person(30), new Person(20)};
        Arrays.sort(persons, new PersonComparator());

        System.out.println(Arrays.toString(persons));
    }
}

class Person {
    private int age;

    public Person(int age) {
        this.age = age;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "age=" + age +
                '}';
    }
}

class PersonComparator implements Comparator<Person> {
    @Override
    public int compare(Person p1, Person p2) {
        return Integer.compare(p1.getAge(), p2.getAge());
    }
}

What you need to do is just implement the compare() method from the Comparator interface and pass an instance of the required class as a second argument to Arrays.sort() as shown in the code sample above.
Now that you know how to sort an array, we will practice with the binarySearch() method.

The binary search is an algorithm with O(log n) complexity that works quite efficiently due to the fact that with each step the number of elements in the search interval is reduced by half.

    byte[] arr = {3, 1, 2};
    byte key = 3;
    Arrays.sort(arr);

    System.out.println("The index is: " + Arrays.binarySearch(arr, key)); // 2

You will need two arguments: the first is the array itself and the second is the value to search for. In return, you will get the index of the specified element. Remember that this algorithm doesn't work correctly with duplicate elements. In such cases, there is no guarantee which element will be found.

Converting arrays

The Arrays class also provides us with two methods for converting arrays. They are:

  • Arrays.asList()

  • Arrays.stream()

The first method, Arrays.asList(), converts an array into a List:

    Byte[] arr = {2, 3, 4};
    List<Byte> list = Arrays.asList(arr);

As you may have noticed, we declared the array using the Byte class. The reason for it is that this method doesn't accept primitive type arrays. You should use their wrapper classes instead.
Arrays.stream(), the last and probably one of the most useful methods this class gives us, converts an array into a stream.

    int[] arr = {2, 3, 4};
    int max = Arrays.stream(arr).max().getAsInt();

This method opens up the opportunities to use the power of streams to perform operations such as finding minimum and maximum values, the sum of all elements, performing filtering operations, and so on.

Read more on this topic in Multidimensional arrays in Java on Hyperskill Blog.

Conclusion

This topic is an overview of java.util.Arrays, an important utility class providing us with useful methods to operate on arrays. Knowing the extent of its functionality will help us not to waste time on the implementation of redundant methods. Study them all and don't forget to take full advantage of them!

50 learners liked this piece of theory. 3 didn't like it. What about you?
Report a typo