17. april 2007 - 11:42Der er
5 kommentarer og 1 løsning
deep copy et arrayList til et andet arrayList
Hej. jeg prøver at lave en deep copy af et arrayList til et andet arrayList, som ikke skal referere til det samme. som dette: ArrayList<String> ordre1 = new ArrayList<String>(); ArrayList<String> ordre2 = new ArrayList<String>();
ordre2 skal indeholde det samme som ordre1, så man kan ændre værdierne i ordre1 uden at det ændres i ordre2. Der er set nogle lange forklaringer inde på SUN`s hjemmeside, men er der ikke noget simpelt man kan gøre...?
Denne side indeholder artikler med forskellige perspektiver på Identity & Access Management i private og offentlige organisationer. Artiklerne behandler aktuelle IAM-emner og leveres af producenter, rådgivere og implementeringspartnere.
Nae. arrayList1.get(i) henter blot en reference til det objekt der ligger i arrayList1og den reference lægges over i arraylist2. begge lister peger på de samme instanser af objekterne.
For at lave deep copu skal alle de lagrede objekter være cloneable, så kan du gøre det (i eet niveau) med: arrayList2.add( (<Obj-type>)( (<Obj-type>)arrayList1.get(i) ).clone() );
Men hvis objekterne selv indeholder andre objekter må du i hver <Obj-type> class lave en clone metode public Object clone() { // her klones objekterne indeni dette objekt }
Og pas på. hvis en af de ting der ligger i arrayList1 er arrayList1 får du en uendelig rekursion når den igen prøver at clone alt den har i sig (inklusive sig selv).
okay... hvorfor udskriver følgende så "tekst" og ikke "tekst2" ?:
import java.util.ArrayList; public class ArrayLists { public static ArrayList<String> test1= new ArrayList<String>(); public static ArrayList<String> test2= new ArrayList<String>(); public static void main(String[] args) { test1.add("tekst"); copyArraylist(); test1.remove(0); test1.add("tekst2"); System.out.println(test2); } public static void copyArraylist() { for(int i = 0 ; test1.size() > i ; i++) { test2.add(test1.get(i)); } } }
Fordi der kun er een objekt reference kopieret til test2, og den peger på strengen "tekst".
Prøv denne test:
import java.util.ArrayList;
public class strengOgTal { public String streng; public Int tal; public StrengOgTal( String s, int nr ) { streng = s; tal = nr; } public String toString() { return " ["+streng +":" +tal +"] "; } }// endclass StrengOgTal
public class ArrayLists { public static ArrayList<String> test1= new ArrayList<StrengOgTal>(); public static ArrayList<String> test2= new ArrayList<StrengOgTal>(); public static void main(String[] args) { test1.add( new StrengOgTal( "tekst", 1 ) ); copyArraylist(); StrengOgTal sTest = test1.get(0); test1.add( new StrengOgTal( "tekst2",2 ) ); System.out.println(test2); sTest.streng = "en helt anden tekst"; //ændrer første element i test1 System.out.println(test2); } public static void copyArraylist() { for(int i = 0 ; test1.size() > i ; i++) { test2.add(test1.get(i)); } } }
ja. Streng-objekter er specielle fordi det er umuligt at i dem, det eneste man kan gøre er at slippe den streg og lave en ny med et andet indhold. Så hvis du har
String t = "Olsen"; class ObjA { Public String t1 = t; }
vil instanser af ObjA starte med at pege på "Olsen" men t = "Jensen"; ændrer ikke indholdet af strengen t1 i nogen instanser af ObjA. det ændrer blot pegepinden t så den peger på jensen. Den 'gamle' pegepind der blev kopieret i objekterne peger stadig på "Olsen"
Jeg opdagede en masse fejl i min kode ovenfor, så her er et bedre eksempel:
// start på fil. kald filen ArrayLists.java import java.util.ArrayList;
class StrengOgTal implements Cloneable { String streng; int tal; StrengOgTal( String s, int nr ) { streng = s; tal = nr; } public String toString() { return " ("+streng +":" +tal +") "; } public Object clone() { try { return super.clone(); } catch (CloneNotSupportedException e) { return new StrengOgTal( "Der er noget helt galt her", 0 ); } } }// endclass StrengOgTal
public class ArrayLists {
public static ArrayList<StrengOgTal> test1= new ArrayList<StrengOgTal>(); public static ArrayList<StrengOgTal> test2= new ArrayList<StrengOgTal>();
public static void main(String[] args) {
System.out.println( "\ntest nr 1:" ); test1.add( new StrengOgTal( "tekst", 1 ) ); copyArraylist(); test1.add( new StrengOgTal( "tekst2", 2 ) ); System.out.println( "test1: "+test2); test1.get(0).streng = "en helt anden tekst"; //ændrer første element i test1 System.out.println( "test2: "+test2); //og første element i test2 følger med System.out.println( "test1: "+test1);
System.out.println( "\ntest nr 2:" ); test1.get(0).streng = "tekst"; // ændrer første element i test1 tilbage test2= new ArrayList<StrengOgTal>(); // start igen med ny test2 liste copyArraylist2(); test1.get(0).streng = "en helt anden tekst"; //ændrer første element i test1 System.out.println( "test2: "+test2); //men ikke i den anden liste System.out.println( "test1: "+test1); test2.get(0).tal = 9999; //ændrer første element i test2 System.out.println( "test2: "+test2); System.out.println( "test1: "+test1); //men ikke i den anden liste } public static void copyArraylist() { for(int i = 0 ; test1.size() > i ; i++) { test2.add(test1.get(i)); } } public static void copyArraylist2() { // kopierer i eet niveau, // og det er godt nok her fordi String er et atomisk objekt for(int i = 0 ; test1.size() > i ; i++) { test2.add((StrengOgTal)test1.get(i).clone()); } } } // slut på filen
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.