이다 : 그것은 2 차원 배열입니다 때문에, 당신은 중첩 루프가 필요합니다. 자세한 대답을 원한다면 여기 내 주석을 읽어야합니다 : Java is NEVER pass-by-reference, right?...right? 또는 여기 : In Java, what is a shallow copy?
그래서 배열이 포인터이기 때문에 포인터가있는 포인터를 복제하면 어떻게됩니까? 처음에는 포인터가 실제 복사되었지만 이러한 포인터는 복제되지 않은 다른 오브젝트를 가리 킵니다. 그래서 당신이 복제하고 싶다면, 나는 배열을 사용하지 않고 "더 힘든"데이터 구조를 제안한다 : 클래스. 또 다른 가능성은 배열 내에 배열을 저장하지 않을 것입니다 ... 저는 컨테이너에 대해서만 배열을 사용합니다!
하지만 배열과 (어쨌든 일부 OO 원칙을 위반하고 코드가 추악하게 보이기 때문에) 가능한 모순 때문에 내가 다룰 수 없으므로 Java 다차원 generics에 대한 세부 정보를 제공 할 수는 없습니다. .
편집
내가 복제 방법은 클래스 내에 배열 작동하는 방법을 몇 가지 테스트를 실행하고, 어떤 문제가 어느 우리가 해결 방법.
첫 번째 테스트 데이터 구조 :
public class Foobar implements Cloneable {
String[] array;
public Foobar() {
this.array = new String[10];
}
public String getValue(){
return array[0];
}
public String[] getArray(){
return array;
}
public void setArray(String[] array){
this.array = array;
}
@Override
public Object clone(){
try{
Foobar foobar = (Foobar) super.clone();
foobar.setArray(array);
return foobar;
}
catch(Exception e){
return null;
}
}
}
이제 컨트롤러 :
String[] array = new String[10];
array[0] = "111";
Foobar foo1 = new Foobar();
foo1.setArray(array);
Foobar foo2 = foo1; //Alternation: Foobar foo2 = (Foobar) foo1.clone();
System.out.println("Instance: "+foo1.getArray()+" with value: "+foo1.getValue());
System.out.println("Instance: "+foo2.getArray()+" with value: "+foo2.getValue());
array[0] = "999";
System.out.println("Instance: "+foo1.getArray()+" with value: "+foo1.getValue());
System.out.println("Instance: "+foo2.getArray()+" with value: "+foo2.getValue());
항상 그 모양을
테스트 결과 - 내가 사용하는 경우에 상관없이 = 또는 복제() :
Instance: [Ljava.lang.String;@42e816 with value: 111
Instance: [Ljava.lang.String;@42e816 with value: 111
Instance: [Ljava.lang.String;@42e816 with value: 999
Instance: [Ljava.lang.String;@42e816 with value: 999
이것은 이 아니요.입니다.
해결 방법은 무엇입니까? 나는 모든 데이터 구조 클래스에서이 일을 제안 :
Foobar foo2 = foo1.copy(); //nice and easy!!
이 솔루션의 장점 :
public class Foobar implements Serializable {
//any class variables...it doesn't matter which!
public Foobar() {
//do initialisation here...it doesn't matter what you do!
}
public Foobar copy(){
try{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(this);
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
Foobar foobar = (Foobar) ois.readObject();
return foobar;
}
catch(Exception e){
return null;
}
}
}
그래서 당신은 코드의 한 라인을 구현하여 전체 복사본을 얻을 것이다 그것은 충분히 보통이다 Serializable 인터페이스를 구현해, 클래스를 "카피 가능"으로합니다. 그리고 그렇지 않다면 Serializable Javadoc에 쓰여진 것을 읽음으로써 어떤 문제를 해결할 수 있습니다!
더 많은 정보 : 어떤 종류의 개체가 "복사 가능"으로 만들고 싶은지 상관 없으므로이 문제에 더 이상 시간을 할애 할 필요가 없습니다. 결국, 위의 코드는 그 이후로 Java에 심층적으로 포함 된 가장 간단하고 빠른 솔루션이며 RAM 만 사용합니다! (덕분에 ByteArrayOutputStream)
즐기십시오!
UPDATE : (: 당신은 서로 완전히 독립적 인 개체가해야하는 경우 일반적으로) 당신이 스레드를 처리하는 경우에만 임시 스택을 원하는 경우 객체의 복사본을 사용할 필요가 또는 참고. 그렇지 않으면 어떤 사본도 만들어서는 안됩니다! 또한 파일이나 소켓에 데이터를 쓰는 경우 복사본이 필요하지 않습니다. 더군다나 나는 실제로 사용되는 경우에만 복사 방법을 구현하는 것이 좋습니다. 데이터 구조 (모델)입니다. 따라서이 강력한 방법을 사용하여 조심하십시오 (그렇지 않으면 앱 속도가 느려지거나 아무 이유없이 수백만 개의 사본을 작성하는 경우 Java VM 저장소를 채울 수 있습니다. 실제로 스택 오버 플로우가 발생합니다).
편집
나는 조금 더이 문제에 대한 작업을했다. 갑자기 알았 기 때문에 Java API에없는 "원시"배열의 public clone() 메서드가 있습니다! (SUN에서 String [] 또는 int [] ;-)와 같은 배열의 "부활절 달걀"
그리고 실제 배열을 Foobar의 기본 데이터 구조로 사용합니다 (ArrayLists가 아닙니다!
@Override
public Object clone(){
try{
Foobar foobar = (Foobar) super.clone();
String[] arrayClone = array.clone(); //who thought that this is possible?!
foobar.setArray(arrayClone);
return foobar;
}
catch(Exception e){
return null;
}
}
을 그리고 지금 우리가 바로 상자에서이 결과를 얻을 :), I는 다음과 같이() 위 클래스의 복제 방법을 변경할 수 있습니다 해결할
Instance: [Ljava.lang.String;@42e816 with value: 111
Instance: [Ljava.lang.String;@9304b1 with value: 111
Instance: [Ljava.lang.String;@42e816 with value: 999
Instance: [Ljava.lang.String;@9304b1 with value: 111
문제를 "더블 - 중첩 " 개체! 보시다시피, 클론은 원본과는 다른 독립적 인 객체를 가지고 있습니다 ... 그러므로 foo1.equals (foo2))는 false가됩니다!
솔루션 : 클래스의 복제 방법에서 모든 클래스 변수를 복제해야합니다. (그러나 일부 클래스 변수가 ArrayLists 또는 그 이상의 차원 배열 인 경우이 솔루션조차 작동하지 않습니다!)
마지막으로 실제 문제는 무엇입니까? ArrayList 클래스는 배열을 복제하지 않고 Array 클래스의 copyOf 메서드 만 호출하므로 유해합니다. ArrayList 클래스의 복제 메서드를 절대로 사용하지 마십시오. 복제 메서드가 작동하지 않으므로 ArrayList의 클래스를 상속하지 않습니다! (ArrayList 클래스가 프리미티브와 객체 만 포함하는 경우에만 작동합니다. 그렇지 않으면 위의 쉬운 ByteArray 솔루션을 사용하십시오!).
Object [] []와 같은 더 많은 차원의 배열을 사용하면 항상 위의 ByteArray 솔루션을 구현해야하므로 복제 할 수 없습니다. 배열이 거대한 경우에는 시간이 걸리고 일부 RAM이 필요할 수도 있습니다.
이제 복제 전문가입니다! :-D
Java의 다차원 배열은 배열에 대한 포인터의 배열입니다. Clone은 첫 번째 배열 만 복제합니다. –
그렇다면 어떻게해야합니까? 한 배열에서 다른 배열로 원시 int를 복사하는 루프를 만들어야합니까? – AndreiBogdan
내부 배열을 복제하는 루프를 만들어야합니다. 또는 Arrays 클래스에서이 작업을 수행 할 수있는 함수가있을 수 있습니다. 실제로 발명 된 이후로 클래스를 실제로 연구하지 않았습니다. –