Avatar billede renebmadsen Nybegynder
17. april 2007 - 11:42 Der 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...?
Avatar billede scorp-d Nybegynder
17. april 2007 - 13:32 #1
public static void copyArraylist(ArrayList<String> arrayList1,ArrayList<String> arrayList2 )
    {
        for(int i = 0 ; arrayList1.size() > i ; i++)
        {
            arrayList2.add(arrayList1.get(i));
        }
    }

Burde løse det..
Avatar billede jakoba Nybegynder
17. april 2007 - 14:00 #2
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).

mvh JakobA
Avatar billede scorp-d Nybegynder
17. april 2007 - 18:39 #3
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));
        }
    }
}

Er der noget jeg har misforstået ?
Avatar billede jakoba Nybegynder
17. april 2007 - 19:27 #4
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));
        }
    }
}
Avatar billede scorp-d Nybegynder
17. april 2007 - 19:59 #5
Men ville det andet fungere hvis man kun har med strenge at gøre ?
Avatar billede jakoba Nybegynder
17. april 2007 - 22:27 #6
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
Avatar billede Ny bruger Nybegynder

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.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester