[java] 배열의 복사본 만들기

a지속적으로 업데이트되는 배열 이 있습니다. 말해 보자 a = [1,2,3,4,5]. 정확한 사본을 만들어 a전화해야합니다 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]
}

그러나 그것은 제대로 작동하지 않는 것 같습니다. 딥 카피 등과 같은 고급 용어를 사용하지 마십시오. 그 의미를 모릅니다.



답변

System.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.copyOfa.clone()작은 배열 보다 빠를 수 있습니다 . 두 copy 요소가 똑같이 빠르지 만 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의 멋진 설명

자바 배열 복사 방법

Object.clone () : Object 클래스는 clone () 메소드를 제공하며 java의 array도 Object이므로이 메소드를 사용하여 전체 배열 복사를 수행 할 수 있습니다. 배열의 부분 복사본을 원할 경우이 방법이 적합하지 않습니다.

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

Arrays.copyOf () : 배열의 처음 몇 요소 또는 배열의 전체 사본을 복사하려는 경우이 메소드를 사용할 수 있습니다. 분명히 System.arraycopy ()와 같이 다재다능하지는 않지만 혼란스럽고 사용하기 쉽지 않습니다.

Arrays.copyOfRange () : 시작 인덱스가 0이 아닌 배열의 요소를 거의 복사하지 않으려면이 메서드를 사용하여 부분 배열을 복사 할 수 있습니다.


답변

이 “배열을 복사하는 더 좋은 방법”이 실제로 문제를 해결하지 못할 것이라고 생각합니다.

당신은 말한다

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

해당 루프를 살펴보면 작동하지 않는 확실한 이유 는 없습니다.

  • 당신은 어떻게 든이 ab배열이 엉망 (예 ab같은 배열을 참조), 또는
  • 응용 프로그램이 다중 스레드이며 다른 스레드가 a동시에 배열을 읽고 업데이트합니다 .

두 경우 모두 복사를 수행하는 대체 방법으로는 근본적인 문제가 해결되지 않습니다.

첫 번째 시나리오에 대한 해결책은 분명합니다. 두 번째 시나리오에서는 스레드를 동기화하는 방법을 찾아야합니다. 원자 배열 클래스는 원자 복사 생성자 또는 복제 메소드가 없기 때문에 도움이되지 않지만 원시 뮤텍스를 사용하여 동기화하면 트릭이 수행됩니다.

(귀하의 질문에는 이것이 실제로 스레드와 관련이 있다고 생각하게하는 힌트가 있습니다 (예 : a끊임없이 변화하는 진술 ).)


답변

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

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


답변

배열에서 길이를 호출하는 모든 솔루션은 코드 중복 null 체커를 추가하십시오.

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();
    }
}

휠을 발명하지 말고 필요한 모든 점검이 이미 수행 된 유틸리티 클래스를 사용하는 것이 좋습니다. 아파치 커먼즈의 ArrayUtils를 고려하십시오. 코드가 짧아집니다.

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

여기에서 찾을 수있는 Apache Commons