HOWTO · Java

How to Get the Subset of an Array in Java

This tutorial demonstrates how to get a subset of an array in Java.

On this page

To copy the first n elements of an array, use a prefix operation. To select a contiguous portion elsewhere in the array, use a start index and an exclusive end index. Java offers several ways to make that range copy, with different tradeoffs for primitive arrays, object arrays, dependencies, and list processing.

The examples below show the relevant imports and complete programs. The six included Java examples have supplied successful execution evidence. The inline Apache Commons Lang invocation has no supplied execution evidence. For each range example, the start is included and the end is excluded.

Get an Array Prefix with Arrays.copyOf()

Arrays.copyOf() starts at index zero and accepts the requested output length; it cannot select an arbitrary starting index. This example copies four strings. It uses the two-argument overload, which preserves the source array’s type. The overload accepting a third Class argument is useful when the desired destination array type differs.

Run this example:

import java.util.Arrays;

public class ArrayPrefix {
    public static void main(String[] args) {
        String[] names = {"Ada", "Grace", "Linus", "Ken", "Margaret"};
        String[] prefix = Arrays.copyOf(names, 4);
        System.out.println(Arrays.toString(prefix));
    }
}

If the requested length exceeds the source length, copyOf pads the new array with the component type’s default values (for example, null for a reference array and 0 for an int[]). Choose this method when the desired result begins at the first element.

Copy an Array Range with Arrays.copyOfRange()

Arrays.copyOfRange() copies from from through the element before to, returning a new array. See the explanation of a range of elements from the original array.

import java.util.Arrays;

public class ArrayRange {
    public static void main(String[] args) {
        int[] values = {10, 20, 30, 40, 50, 60};
        int[] part = Arrays.copyOfRange(values, 2, 5);
        System.out.println(Arrays.toString(part));
    }
}

The indexes select 30, 40, and 50. A range ending at the array length is valid. If to is beyond the source length, this method pads the copied tail with default values; a negative start or a start beyond the source length is not a valid range. An end before the start is also invalid. Use this method for a straightforward range copy, including a prefix by setting from to zero.

Select an Array Range with IntStream

IntStream is in java.util.stream; the supplied source identifies this approach as requiring Java 8 or later. This is a minimum for the approach, not a statement about the runtime used to execute the article. IntStream.range(start, end) produces indexes, and mapToInt looks up each selected value before toArray() creates the result.

import java.util.Arrays;
import java.util.stream.IntStream;

public class StreamRange {
    public static void main(String[] args) {
        int[] values = {10, 20, 30, 40, 50, 60};
        int[] part = IntStream.range(2, 5).map(i -> values[i]).toArray();
        System.out.println(Arrays.toString(part));
    }
}

The indexes have the same inclusive-start, exclusive-end meaning as copyOfRange. This pattern is handy when selection naturally fits a stream pipeline; for a simple copy, the array utility is shorter. Keep indexes within the source array because the mapping function reads that array directly.

Copy an Array Range with System.arraycopy()

System.arraycopy() copies a specified count between arrays. Its source offset identifies the first source element; the destination offset identifies where it is placed. Allocate the destination to the range length, to - from, and use that same length as the copy count.

import java.util.Arrays;

public class ArrayCopyRange {
    public static void main(String[] args) {
        char[] letters = {'a', 'b', 'c', 'd', 'e', 'f'};
        int from = 2;
        int to = 5;
        int length = to - from;
        char[] part = new char[length];
        System.arraycopy(letters, from, part, 0, length);
        System.out.println(Arrays.toString(part));
    }
}

The destination begins at zero, so this creates a compact range copy. The source range and destination capacity must both accommodate the requested count. This lower-level option is useful when copying into an existing destination at a chosen offset; for a new array, Arrays.copyOfRange() usually communicates intent more clearly.

Use Apache Commons Lang ArrayUtils.subarray()

Apache Commons Lang is an external dependency; the JDK alone does not provide ArrayUtils. Add the commons-lang3 library to the project and import org.apache.commons.lang3.ArrayUtils before using ArrayUtils.subarray(). Its start is inclusive and its end is exclusive, and it returns a new range array. This packet has no execution evidence for the external dependency, so the invocation is shown inline rather than as an allegedly runnable program: Integer[] part = ArrayUtils.subarray(values, 1, 4);. The input and result use Integer[]; primitive arrays such as int[] are a different type and do not match that generic invocation. This option suits projects that already use Commons Lang.

Use a List and subList()

For object arrays, Arrays.asList() gives a fixed-size list backed by the array. subList(from, to) returns a view of that list, not an array copy. Calling toArray() with a correctly typed destination produces the new array. This adds conversions and is most useful when subsequent work already uses list operations. See converting an array to a list in Java.

import java.util.Arrays;
import java.util.List;

public class ListRange {
    public static void main(String[] args) {
        String[] values = {"red", "green", "blue", "gold"};
        List<String> view = Arrays.asList(values).subList(1, 3);
        String[] part = view.toArray(new String[0]);
        System.out.println(Arrays.toString(part));
    }
}

As with other list ranges, from is included and to is excluded. The view reflects changes to the backing array’s elements. The array returned by toArray() is a separate array.

Write a Custom Subset Method

A custom method is useful when the copy needs application-specific checks or additional processing. For a plain contiguous range, use Arrays.copyOfRange() instead of duplicating its work. This generic method takes reference-type arrays and delegates range behavior to that library method:

import java.util.Arrays;

public class CustomArrayRange {
    public static <T> T[] subset(T[] values, int from, int to) {
        return Arrays.copyOfRange(values, from, to);
    }

    public static void main(String[] args) {
        String[] values = {"oak", "pine", "elm", "ash"};
        System.out.println(Arrays.toString(subset(values, 1, 3)));
    }
}

This preserves the component type of the input reference array. Primitive arrays need a corresponding overload for each primitive type or a different approach. Selecting values by a condition, such as keeping only even numbers, is filtering rather than extracting a contiguous range; filtering can change the number and positions of the selected elements.

Choose an Array Subset Approach

Use Arrays.copyOf() for a prefix or a new array of a requested length. Use Arrays.copyOfRange() for a direct contiguous range, including primitive arrays. Choose IntStream when the index selection belongs in a stream pipeline, and System.arraycopy() when explicit destination placement matters. Use ArrayUtils.subarray() when the project already depends on Apache Commons Lang. subList() is appropriate when list operations are useful and a view is acceptable before converting back. A custom method fits extra application logic; for an ordinary range, the standard array utility is simpler. In all cases, check that the indexes describe the elements you intend to include and remember that the end index is exclusive.