programing

어레이 복사

firstcheck 2022. 7. 9. 09:23
반응형

어레이 복사

는 배열이 .a지속적으로 업데이트되고 있습니다. '우리'라고 합시다.a = [1,2,3,4,5]의 복사본을 정확하게 복사해야 합니다.a 그것을 고 it부 it it라고 부른다.b.a로 바뀔 예정이었다.[6,7,8,9,10],b[1,2,3,4,5]떻게게 하면 ?? ???는 ㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇ다를 먹어 .for다음과 같이 합니다.

for(int i=0; i<5; i++) {
    b[i]=a[i];
}

제대로 작동하지 않는 것 같습니다.딥 카피 등의 고급 용어는 사용하지 말아 주세요.무슨 뜻인지 모르니까

시스템을 사용해 볼 수 있습니다.arraycopy()

int[] src  = new int[]{1,2,3,4,5};
int[] dest = new int[5];

System.arraycopy( src, 0, dest, 0, src.length );

단, 대부분의 경우 clone()을 사용하는 것이 좋습니다.

int[] src = ...
int[] dest = src.clone();

사용할 수 있습니다.

int[] a = new int[]{1,2,3,4,5};
int[] b = a.clone();

뿐만 아니라.

카피를 작성하려면:

int[] a = {1,2,3,4,5};

방법은 다음과 같습니다.

int[] b = Arrays.copyOf(a, a.length);

Arrays.copyOf 스몰 어레이보다 빠를 수 있습니다.두 요소 모두 동일한 속도로 복사되지만 clone()이 반환됩니다.Object.int[]바이트 코드에는 다음과 같이 표시됩니다.

ALOAD 1
INVOKEVIRTUAL [I.clone ()Ljava/lang/Object;
CHECKCAST [I
ASTORE 2

http://www.journaldev.com/753/how-to-copy-arrays-in-java의 좋은 설명

Java 어레이 복사 방법

Object.clone(): 객체 클래스는 clone() 메서드를 제공합니다.자바의 어레이도 오브젝트이기 때문에 이 메서드를 사용하여 완전한 어레이 복사를 실현할 수 있습니다.어레이의 부분 복사를 원하는 경우 이 방법은 적합하지 않습니다.

System.arraycopy(): 시스템 클래스 arraycopy()는 어레이의 부분 복사를 수행하는 가장 좋은 방법입니다.복사할 요소의 총 수 및 원본 및 대상 배열 인덱스 위치를 쉽게 지정할 수 있습니다.를 들어 시스템입니다.arraycopy(source, 3, destination, 2, 5)는 소스 인덱스의 세 번째 인덱스에서 두 번째 인덱스로 5개의 요소를 소스부터 수신처로 복사합니다.

Arrays.copyOf(): 어레이의 처음 몇 가지 요소 또는 어레이의 전체 복사본을 복사하는 경우 이 방법을 사용할 수 있습니다.분명히 시스템처럼 다재다능한 것은 아닙니다.arraycopy()를 사용합니다.

Arrays.copyOfRange(): 어레이의 요소를 몇 개 복사하는 경우 시작 인덱스가 0이 아닌 경우 이 메서드를 사용하여 부분 어레이를 복사할 수 있습니다.

이러한 「어레이를 카피하는 보다 좋은 방법」으로는, 고객의 문제를 해결할 수 없을 것 같습니다.

당신이 말하길

[...]와 같은 포루프를 시도했는데 제대로 작동하지 않는 것 같습니다.

루프를 보면 안 될 이유가 없어다음 경우를 제외하고:

  • 어떻게 해서든a ★★★★★★★★★★★★★★★★★」b 어이가(((((((((((((((:a ★★★★★★★★★★★★★★★★★」b를 참조한다) """를 참조한다")
  • 의 어플리케이션은 여러 로 구성되어 , .a동시에 배열합니다.

어느 경우든 다른 복사 방법으로는 근본적인 문제를 해결할 수 없습니다.

첫 번째 시나리오의 수정은 명백합니다.두 번째 시나리오에서는 스레드를 동기화하는 방법을 찾아야 합니다.atomic 어레이 클래스는 atomic copy 컨스트럭터나 클론 메서드가 없기 때문에 도움이 되지 않지만 원시 mutex를 사용하여 동기화하면 도움이 됩니다.

(에는 이것이 를 들어,과 같이 있습니다.예를 들어 다음과 같은 진술이 있습니다.a끊임없이 변화하고 있습니다.)

Java에서 Arrays.copyOf()를 사용해 볼 수 있습니다.

int[] a = new int[5]{1,2,3,4,5};
int[] b = Arrays.copyOf(a, a.length);

어레이에서 호출하는 모든 솔루션에서 코드 용장 늘체커를 추가합니다.다음 예를 참고해 주세요.

int[] a = {1,2,3,4,5};
int[] b = Arrays.copyOf(a, a.length);
int[] c = a.clone();

//What if array a comes as local parameter? You need to use null check:

public void someMethod(int[] a) {
    if (a!=null) {
        int[] b = Arrays.copyOf(a, a.length);
        int[] c = a.clone();
    }
}

휠을 발명하지 말고 필요한 모든 검사가 이미 완료된 유틸리티 클래스를 사용하는 것이 좋습니다.Apache Commons의 Array Utils를 검토합니다.코드 단축:

public void someMethod(int[] a) {
    int[] b = ArrayUtils.clone(a);
}

Apache Commons(커먼스)에서 찾을 수 있습니다.

를 사용할 수도 있습니다.

:

public static void main(String[] args) {
    int[] a = {1,2,3};
    int[] b = Arrays.copyOfRange(a, 0, a.length);
    a[0] = 5;
    System.out.println(Arrays.toString(a)); // [5,2,3]
    System.out.println(Arrays.toString(b)); // [1,2,3]
}

이 방법은 와 비슷하지만 더 유연합니다.둘 다 사용System.arraycopy보닛 밑에

참조:

raw 어레이가 ArrayListArrays을 사용법소스 코드를 살펴보면 어레이의 복사본을 얻는 가장 좋은 방법은 다음과 같습니다.은 방어적인 이 잘 있습니다. 이 프로그램은System.arraycopy()메서드에 비논리적인 파라미터를 입력하면 체크되지 않은 예외가 많이 발생합니다.

둘 중 하나를 사용하여 첫 번째 복사부터Nth이치노

public static <T> T[] copyOf(T[] original, int newLength)

지정된 배열, 잘라내기 또는 Null(필요한 경우)로 채워진 배열을 복사하여 지정된 길이를 갖습니다.원래 배열과 복사본 모두에서 유효한 모든 인덱스에 대해 두 배열에는 동일한 값이 포함됩니다.복사본에서 유효하지만 원본이 아닌 인덱스의 경우 복사본에 null이 포함됩니다.이러한 인덱스는 지정된 길이가 원래 배열의 길이보다 큰 경우에만 존재합니다.결과 어레이는 원래 어레이와 완전히 동일한 클래스입니다.

2770
2771    public static <T,U> T[] More ...copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
2772        T[] copy = ((Object)newType == (Object)Object[].class)
2773            ? (T[]) new Object[newLength]
2774            : (T[]) Array.newInstance(newType.getComponentType(), newLength);
2775        System.arraycopy(original, 0, copy, 0,
2776                         Math.min(original.length, newLength));
2777        return copy;
2778    }

또는Arrays.copyOfRange()또한 다음과 같은 효과를 발휘합니다.

public static <T> T[] copyOfRange(T[] original, int from, int to)

지정된 배열의 지정된 범위를 새 배열로 복사합니다.범위의 초기 인덱스(from)는 0과 original.length 사이에 있어야 합니다.original[from]의 값은 복사본의 초기 요소에 배치됩니다(== original.length 또는 == to는 제외).원래 배열의 후속 요소의 값은 복사본의 후속 요소에 배치됩니다.범위(to)의 최종 인덱스는 original.length보다 크거나 같아야 합니다.이 경우 인덱스가 original.length - from보다 크거나 같은 복사본의 모든 요소에 null이 배치됩니다.반환되는 어레이의 길이는 ~가 됩니다.결과 어레이는 원래 어레이와 완전히 동일한 클래스입니다.

3035    public static <T,U> T[] More ...copyOfRange(U[] original, int from, int to, Class<? extends T[]> newType) {
3036        int newLength = to - from;
3037        if (newLength < 0)
3038            throw new IllegalArgumentException(from + " > " + to);
3039        T[] copy = ((Object)newType == (Object)Object[].class)
3040            ? (T[]) new Object[newLength]
3041            : (T[]) Array.newInstance(newType.getComponentType(), newLength);
3042        System.arraycopy(original, from, copy, 0,
3043                         Math.min(original.length - from, newLength));
3044        return copy;
3045    }

보시는 바와 같이 이 두 가지 기능은 모두 단순한 래퍼 기능입니다.System.arraycopy당신이 하려는 일이 타당하다는 방어적 논리로요

System.arraycopy 어레이를 복사하는 가장 빠른 방법입니다.

어레이의 늘세이프 카피의 경우는, 옵션으로서Object.clone()답변에 제시된 방법.

int[] arrayToCopy = {1, 2, 3};
int[] copiedArray = Optional.ofNullable(arrayToCopy).map(int[]::clone).orElse(null);

2D 어레이에서도 비슷한 문제가 발생하여 여기까지입니다.메인 어레이를 복사하여 내부 어레이의 값을 변경하고 있었는데 두 복사본 모두 값이 변경되어 놀랐습니다.기본적으로 두 복사본 모두 독립적이지만 동일한 내부 어레이에 대한 참조가 포함되어 있어 원하는 것을 얻기 위해 내부 어레이의 여러 복사본을 만들어야 했습니다.

이것은 딥 카피라고 불리기도 합니다.같은 용어인 '딥 카피'는 전혀 다른 의미로 복잡한 의미를 가질 수도 있습니다.이는 특히 복사된 어레이가 정상적으로 동작하지 않는 이유를 모르는 사람에게 혼란을 줄 수 있습니다.OP의 문제는 아닐지도 모르지만 그래도 도움이 되었으면 합니다.

언급URL : https://stackoverflow.com/questions/5785745/make-copy-of-an-array

반응형