답변:
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();
System.arraycopy
메소드가 시작하기 전에 다양한 사항을 확인해야 함을 알 수 있습니다. 정적 배열 유형에 따라 복사 루프에서는 이러한 검사 중 일부가 필요하지 않습니다.
src.clone()
새로운 배열을 할당하고 수행하는 것보다 읽기 쉽고 오류 가능성이 훨씬 적다는 것 arraycopy
입니다. (또한 빠릅니다.)
당신이 사용할 수있는
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
a.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 루프를 시도했지만 제대로 작동하지 않는 것 같습니다.
해당 루프를 살펴보면 작동하지 않는 확실한 이유 는 없습니다.
a
와 b
배열이 엉망 (예 a
와 b
같은 배열을 참조), 또는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
당신은 또한 사용할 수 있습니다 Arrays.copyOfRange
.
예 :
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]
}
이 방법은와 비슷 Arrays.copyOf
하지만 더 유연합니다. 둘 다 사용합니다System.arraycopy
후드 아래에서 합니다.
참조 :
null 안전 배열의 복사본의 Object.clone()
경우이 답변에 제공된 방법 과 함께 선택 사항을 사용할 수도 있습니다 .
int[] arrayToCopy = {1, 2, 3};
int[] copiedArray = Optional.ofNullable(arrayToCopy).map(int[]::clone).orElse(null);
Optional
객체는 기존 배열에 대한 참조가있는 빈 객체 일뿐입니다. 성능에 미치는 영향에 대해, 실제로 이러한 유형의 구성은 JVM 내부에 인라인하기에 적합한 후보이며 다른 방법보다 더 많은 영향을 미치지 않기 때문에 실제로 영향을 미치는 것으로 판단하기에는 너무 이르다. 더 복잡하거나 그렇지 않은 것으로 간주하는 것은 스타일 문제 (기능적 프로그래밍 대 절차 적 프로그래밍뿐 아니라 절차 적 프로그래밍)입니다.
당신이없는 원시 배열 함께 작업해야하는 경우 ArrayList
다음 Arrays
당신이 필요가 있습니다. 소스 코드를 보면 배열 사본을 얻는 가장 좋은 방법입니다. 그들은 방어적인 프로그래밍을 잘하고 있기 때문에System.arraycopy()
비논리적 매개 변수를 제공하는 경우이 메소드는 검사되지 않은 예외를 많이 발생 있습니다.
Arrays.copyOf()
첫 번째 Nth
요소에서 새로운 짧은 배열로 복사하는 것을 사용할 수 있습니다 .
public static <T> T[] copyOf(T[] original, int newLength)
사본이 지정된 길이를 갖도록 지정된 배열을 복사하거나 널 (필요한 경우)로 채 웁니다. 원본 배열과 복사본 모두에 유효한 모든 인덱스의 경우 두 배열에 동일한 값이 포함됩니다. 사본에서 유효하지만 원본에서는 유효하지 않은 색인의 경우 사본에는 널이 포함됩니다. 이러한 길이는 지정된 길이가 원래 배열의 길이보다 큰 경우에만 존재합니다. 결과 배열은 원래 배열과 정확히 동일한 클래스입니다.
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)
지정된 배열의 지정된 범위를 새 배열로 복사합니다. 범위 (시작)의 초기 색인은 0에서 original.length (포함) 사이에 있어야합니다. original [from]의 값은 (== original.length 또는 == to가 아닌 한) 복사본의 초기 요소에 배치됩니다. 원래 배열의 후속 요소 값은 사본의 후속 요소에 배치됩니다. from (보다 크거나 같아야하는) 범위 (to)의 최종 인덱스는 original.length보다 클 수 있습니다.이 경우 인덱스가 original보다 크거나 같은 사본의 모든 요소에 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
배열을 복사하는 가장 빠른 방법입니다.