HOWTO · Java

Java에서 배열을 슬라이스하는 방법

이 기사는 Java를 사용하여 배열을 하위 배열로 슬라이싱하는 데 도움이 될 것입니다.

이 페이지의 내용

Java 배열을 슬라이스하려면 연속된 범위의 요소들을 새 배열로 복사합니다. 아래 예제들은 시작 인덱스는 포함하고 종료 인덱스는 제외하는 범위를 사용합니다. fromIndex는 포함되고 toIndex는 포함되지 않는 첫 번째 인덱스입니다. 예를 들어 범위 [2, 5)는 인덱스 2, 3, 4를 선택합니다. 원본 배열은 변경되지 않습니다.

Java에서 요소를 복제하여 배열 슬라이스하기

반복문을 사용하면 인덱스 대응 관계가 분명해집니다. 길이가 toIndex - fromIndex인 결과 배열을 할당한 다음, 선택한 각 값을 결과 배열의 대응하는 위치에 복사합니다.

다음 완성된 프로그램은 정수 배열에서 인덱스 1부터 3까지를 선택합니다.

import java.util.Arrays;

public class ArraySliceLoop {
    static int[] slice(int[] values, int fromIndex, int toIndex) {
        int[] result = new int[toIndex - fromIndex];
        for (int i = 0; i < result.length; i++) {
            result[i] = values[fromIndex + i];
        }
        return result;
    }

    public static void main(String[] args) {
        int[] values = {10, 20, 30, 40, 50};
        int[] part = slice(values, 1, 4);
        System.out.println(Arrays.toString(part));
    }
}

결과는 별도의 배열입니다. 반복 카운터 i는 결과 배열을 기준으로 0부터 시작하고, fromIndex + i는 원본 배열에서 대응하는 요소를 찾습니다. 원본 배열 안에서 유효한 범위를 나타내는 인덱스로 이 메서드를 호출하세요.

Java에서 copyOfRange() 메서드를 사용하여 배열 슬라이스하기

Arrays.copyOfRange()는 범위로부터 새 배열을 직접 만드는 방법을 제공합니다. 이 메서드는 java.util.Arrays에 속하며, from 인수는 포함되고 to 인수는 제외됩니다. 정확한 API 이름에는 copyOfRange()가 포함됩니다.

다음 프로그램은 인덱스 1, 2, 3을 복사합니다.

import java.util.Arrays;

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

반환된 배열에는 선택한 값들이 들어 있으며, 그 배열을 변경해도 원본 배열의 요소가 교체되지는 않습니다. int[]와 같은 기본형 배열에서는 값 자체가 복사됩니다. 객체 배열에서는 배열은 새로 만들어지지만 그 요소들은 동일한 객체를 참조합니다.

Java에서 스트림을 사용하여 배열 슬라이스하기

스트림은 인덱스 스트림을 원본 배열에 매핑함으로써 배열 값을 선택할 수 있습니다. 이 방식은 선택적인 접근법으로 취급하세요. 프로젝트에 구성된 Java 런타임이 필요한 스트림 API를 지원할 때만 사용하세요. 여기서는 어떤 런타임 버전도 가정하지 않습니다.

이 연산은 IntStream.range(fromIndex, toIndex).map(i -> values[i]).toArray()로 작성할 수 있습니다. IntStream.range는 시작을 포함하고 끝을 제외하므로 다른 메서드와 동일한 범위 규칙을 따릅니다. 이 간결한 식은 예시일 뿐입니다. 사용하기 전에 프로젝트에 선언된 Java 런타임에서 API를 사용할 수 있는지 확인하세요. 그 런타임을 알 수 없을 때는 반복문이나 Arrays.copyOfRange()가 간단한 대안입니다.

Java에서 System.arraycopy 메서드를 사용하여 배열 슬라이스하기

System.arraycopy는 지정한 개수의 요소를 한 배열에서 다른 배열로 복사합니다. 길이가 toIndex - fromIndex인 대상 배열을 만든 다음 원본 위치, 대상 위치, 복사할 요소 수를 전달합니다.

import java.util.Arrays;

public class ArraySliceSystemArraycopy {
    public static void main(String[] args) {
        int[] values = {10, 20, 30, 40, 50};
        int fromIndex = 1;
        int toIndex = 4;
        int[] part = new int[toIndex - fromIndex];
        System.arraycopy(values, fromIndex, part, 0, part.length);
        System.out.println(Arrays.toString(part));
    }
}

인수는 원본 배열, 원본 위치, 대상 배열, 대상 위치, 복사할 요소 수 순입니다. 여기서는 대상 위치가 0이므로 선택한 원본 범위가 part를 첫 위치부터 채웁니다. 원본 배열과 대상 배열은 호환되는 요소 타입을 가져야 하며, 위치와 길이가 두 배열 모두에 맞아야 합니다.

Java에서 asList와 subList를 사용하여 배열 슬라이스하기

참조 타입 배열의 경우 Arrays.asList()는 배열이 뒷받침하는 고정 크기 리스트를 만듭니다. subList(fromIndex, toIndex)는 선택한 리스트 범위의 뷰를 반환합니다. 결과가 별도의 배열이어야 한다면 그 뷰를 배열로 변환하세요.

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

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

Arrays.asList()가 반환하는 리스트는 크기가 고정되어 있습니다. 요소를 교체할 수는 있지만 리스트 항목을 추가하거나 제거할 수는 없습니다. 부분 리스트는 그 리스트에 묶인 뷰입니다. toArray()를 호출하면 별도의 배열이 만들어지지만, 객체 요소 자체는 여전히 동일한 객체를 참조합니다. 이 접근법은 String[]와 같은 참조 타입 배열을 위한 것입니다. 기본형 배열에는 위에 나온 반복문, copyOfRange(), System.arraycopy와 같은 기본형 배열용 메서드가 필요합니다.

결론

요소별 복사 과정을 확인하거나 맞춤 설정하고 싶을 때는 반복문을 사용하세요. 배열을 직접 복사하려면 Arrays.copyOfRange()를 선택하고, 대상 위치와 복사 길이를 지정하고 싶을 때는 System.arraycopy를 선택하세요. 프로젝트의 Java 런타임이 필요한 API를 지원한다면 스트림은 인덱스 기반 선택을 제공합니다. 참조 타입 배열에서는 asList와 subList가 리스트 뷰를 제공하며, toArray()를 호출하면 별도의 결과 배열을 얻을 수 있습니다.