2013-04-03 6 views
19

In poche parole, ho un metodo con un parametro ArrayList. Nel metodo modifico il contenuto di ArrayList per scopi rilevanti solo per ciò che viene restituito dal metodo. Pertanto, non desidero che ArrayList venga passato come parametro da modificare (ovvero non passato come riferimento).ArrayList Passando come valore di riferimento e non

Tutto ciò che ho provato è riuscita a ottenere l'effetto desiderato. Che cosa devo fare in modo che io possa fare uso di una copia del ArrayList all'interno solo il metodo, ma non averlo cambiare la variabile reale?

+0

si poteva passare [ 'Collezioni # immodificabile (yourList)'] (http://docs.oracle.com/javase/7/docs/api/java/util/ Collections.html # unmodifiableList (java.util.List)) per inviare una copia non modificabile della tua lista. –

+0

Si potrebbe anche creare una nuova copia di 'ArrayList' nel metodo che lo sta modificando. Anche se non ha effetto sul primo 'ArrayList', qualsiasi oggetto che cambi all'interno verrà comunque modificato ... – MadProgrammer

+0

Stai modificando solo la lista? O anche cosa c'è all'interno della lista? –

risposta

30

Anche se si ha un modo per passare alla lista array come una copia e non con riferimento sarebbe stato solo una copia.

vorrei fare qualcosa di simile:

void foo(final ArrayList list) { 

    ArrayList listCopy = new ArrayList(list); 
    // Rest of the code 

} 

E proprio lavorare sulla lista copiato.

+0

Questo lo farà. Inizialmente ho provato a impostare l'elenco interno uguale al parametro, ma non ha funzionato. Questa è di gran lunga la soluzione più semplice. – fvgs

+1

In effetti, è necessario un periodo di attesa prima di poter accettare una risposta. – fvgs

3

È possibile utilizzare il metodo .clone o un CopyOnWriteArrayList per eseguire una copia, senza influire sull'originale.

+0

IMHO, sembra eccessivo, cosa c'è di sbagliato in 'new ArrayList (list)'? – MadProgrammer

+0

@MadProgrammer Intendi IMMO giusto? – Thihara

4

È possibile passare Collections#unmodifiableList(yourList) al fine di inviare una copia non modificabile della vostra lista. A proposito, il tuo List<Whatever> è passato per il valore dal Java always pass by value, notare che nel metodo foo(List<Whatever> list) non è possibile modificare il valore list ma è possibile modificare il suo contenuto.

public class MyClass { 

    List<Whatever> list = new ArrayList<Whatever>(); 

    public void bar() { 
     //filling list... 
     foo(Collections.unmodifiableList(list)); 
    } 

    public void foo(List<Whatever> list) { 
     //do what you want with list except modifying it... 
    } 
} 
1

Basta clonarlo.

public ArrayList cloneArrayList(ArrayList lst){ 
    ArrayList list = new ArrayList(); 
    for (int i=0; i<lst.size(); i++){ 
     list.add(lst.get(i)); 
    } 
    return list; 
} 

Add suggerito nei commenti, è possibile utilizzare anche

ArrayList copy = new ArrayList(original); 

e anche

ArrayList copy = new ArrayList(); 
copy.addAll(original); 
+2

IMHO, sembra eccessivo, cosa c'è di sbagliato in 'new ArrayList (list)'? – MadProgrammer

+1

E perché no? AddAll'? – wchargin

+0

Non so dell'esistenza di 'new ArrayList (list)'. Scusate. –

13

è possibile creare una copia del ArrayList utilizzando costruttore di copia di ArrayList:

ArrayList copy = new ArrayList(original); 

Ma se anche gli elementi della lista sono oggetti, devi essere consapevole che modificare un membro della copia modificherà anche quel membro nell'originale.

2

Prova questo in voi metodo:

void method(List<Integer> list) { 
     List copyList = new ArrayList<Integer>(); 
     copyList.addAll(list); // This will create a copy of all the emlements of your original list 
    } 
+0

Ancora meglio fare 'nuovo ArrayList (lista)' –

1

Non sono sicuro sul motivo per cui, anche dopo new ArrayList<MyObj>(old) l'oggetto è stato ancora cambiando riferimento in luoghi che non avrebbe dovuto. Quindi ho dovuto istanziare una nuova copia degli oggetti all'interno.

Ho fatto un costruttore di copia come quello sulla ArrayList e gli piaceva

newArray = new ArrayList<MyObj>(); 
     for (int i = 0; i < oldArray.size(); i++) { 
      newArray.add(new MyObj(ondArray.get(i))); 
     } 

Spero solo di aiutare qualcun altro se la risposta da Avi non è sufficiente nel tuo caso, come il mio con un codice troppo disordinato per capire = P

0

Sulle linee delle risposte esistenti ma utilizzando l'API ArrayList. È possibile utilizzare il metodo subList(fromIndex, toIndex). Crea in modo esplicito una vista della lista con solo gli elementi desiderati (ovviamente, in sequenza).Qui, anche se modifichi la vista con operazioni di aggiunta/rimozione, non cambierà la lista originale. Ti salva dalla creazione esplicita di una copia.

Qualcosa di simile a questo:

public void recursiveMethod(List<Integer> list) { 
    if(base) 
     return; 
    recursiveCall(list); 

    // following will just create a tail list but will not actually modify the list 
    recursiveCall(list.subList(1, list.size()); 
}