Course – LS – All

Get started with Spring and Spring Boot, through the Learn Spring course:

>> CHECK OUT THE COURSE

1. Overview

We know that Java’s List has the subList() method, which allows us to slice the source List object. However, there’s no standard subArray() method on the array side.

In this tutorial, let’s explore how to get a subarray of a given array in Java.

2. Introduction to the Problem

As usual, let’s understand the problem through an example. Let’s say we have a string array:

String[] LANGUAGES = new String[] { "Python", "Java", "Kotlin", "Scala", "Ruby", "Go", "Rust" };

As we can see, the LANGUAGES array holds some programming language names. Also, since applications are written in “Java”, “Kotlin”, or “Scala” can run on the Java Virtual Machine, let’s say we’d like a subarray containing these three elements. In other words, we want to get from the second to the fourth element (index 1, 2, 3) from the LANGUAGES array:

String[] JVM_LANGUAGES = new String[] { "Java", "Kotlin", "Scala" };

In this tutorial, we’ll address different approaches to solving this problem. Further, for simplicity, we’ll use unit test assertions to verify if each solution works as expected.

Next, let’s see them in action.

3. Using the Stream API

A significant new feature Java 8 brought us is the Stream API. So if the Java version we’re working with is 8 or later, we can slice a given array using the Stream API.

First, we can convert an array to a Stream object using the Arrays.stream() method. We should note that we should use the Arrays.stream() method with three arguments:

  • the array – in this example, it’s LANGUAGES
  • startInclusive – the start index to extract from the array above, inclusive
  • endExclusive – the end index to extract, as the name implies, exclusive

Therefore, to solve our problem, we can pass LANGUAGES, 1, and 4 to the Arrays.stream() method.

Next, let’s create a test to see if it can get our desired subarray:

String[] result = Arrays.stream(LANGUAGES, 1, 4).toArray(String[]::new);
assertArrayEquals(JVM_LANGUAGES, result);

As the code above shows, after we convert the array to a Stream, we can call the toArray() method to convert it back to an array.

If we run the test, it passes. Therefore, it does the job.

4. Using the Arrays.copyOfRange() Method

We’ve learned to use the Stream API to solve the problem. However, the Stream API is only available in Java 8 and later.

If our Java version is 6 or later, we can solve the problem using the Arrays.copyOfRange() method. This method’s arguments are similar to the Arrays.stream() method – the array, the from-index (inclusive), and the to-index (exclusive).

So next, let’s create a test to see if Arrays.copyOfRange() can solve the problem:

String[] result = Arrays.copyOfRange(LANGUAGES, 1, 4);
assertArrayEquals(JVM_LANGUAGES, result);

The test passes if we give it a run. So it solves our problem as well.

5. Using the System.arraycopy() Method

The Arrays.copyOfRange() approach solves the problem by copying a part of the given array to a new array.

When we want to copy a part from an array, apart from the Arrays.copyOfRange() method, we can also use the System.arraycopy() method. So next, let’s solve the problem using this method.

We’ve seen the Arrays.copyOfRange() returns the result subarray. However, the System.arraycopy() method’s return type is void. Therefore, we must create a new array object and pass it to the arraycopy() method. The method fills the copied elements in the array:

String[] result = new String[3];
System.arraycopy(LANGUAGES, 1, result, 0, 3);
assertArrayEquals(JVM_LANGUAGES, result);

The test passes if we run it.

As we can see in the code above, the arraycopy() method has five parameters. Let’s understand what they mean:

  • the source array – LANGUAGE
  • the from index in the source array to copy – 1
  • the target array to hold the copied result – result
  • the start index in the target array to store the copied result – 0
  • the number of elements we want to copy from the source array – 3

It’s worth mentioning that if the result array contains data already, the arraycopy() method may overwrite the data:

String[] result2 = new String[] { "value one", "value two", "value three", "value four", "value five", "value six", "value seven" };
System.arraycopy(LANGUAGES, 1, result2, 2, 3);
assertArrayEquals(new String[] { "value one", "value two", "Java", "Kotlin", "Scala", "value six", "value seven" }, result2);

This time, the result2 array contains seven elements. Further, when we call the arraycopy() method, we tell it to fill the copied data from index 2 in result2. As we can see, the copied three elements have overwritten the original elements as result2.

Also, we should note that System.arraycopy() is a native method, and the Arrays.copyOfRange() method invokes System.arraycopy() internally.

6. Using ArrayUtils From the Apache Commons Lang3 Library

Apache Commons Lang3 is a pretty widely used library. Its ArrayUtils provides a lot of handy methods so that we can work with arrays easier.

Finally, let’s solve the problem using the ArrayUtils class.

Before we start using ArrayUtils, let’s add the dependency to our Maven configuration:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.14.0</version>
</dependency>

Of course, we can always find the latest version in the Maven central repository.

The ArrayUtils class has the subarray() method, which allows us to get a subarray quickly:

String[] result = ArrayUtils.subarray(LANGUAGES, 1, 4);
assertArrayEquals(JVM_LANGUAGES, result);

As we can see, it’s pretty straightforward to solve the problem using the subarray() method.

7. Conclusion

In this article, we’ve learned different approaches to getting a subarray from a given array.

As usual, all code snippets presented here are available over on GitHub.

Course – LS – All

Get started with Spring and Spring Boot, through the Learn Spring course:

>> CHECK OUT THE COURSE
res – REST with Spring (eBook) (everywhere)
Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.