Como clonar List (Generics)?

Tenho uma list generica que foi retornada por um metodo de um objeto xml.
Porem quero fazer um clone desa list pq se eu alterar a list ele altera o xml tb (nao quero isso)
entao pensei em clonar a List mas ela nao implementa o metodo Clone.

Alguém sabe como posso fazer uma copia de uma list ja existente de forma que se eu alterar a nova lista
a original nao seja alterada ?

Se não me engano

Collections.copy(dest, src)

pode resolver teu problema.

List infelizmente não consegue realizar clone, mas a LinkedList / ArrayList sim!

[code]
public class TesteArrayCLone {
public static void main(String[] args) {
new TesteArrayCLone();
}

TesteArrayCLone() {
	ArrayList<String> nomes = new ArrayList<String>();
	nomes.add("aa");
	nomes.add("bb");
	balbla(nomes);
	
	
	for(String n: nomes) System.out.println(n);
}

private void balbla(ArrayList<String> nomes) {
	ArrayList<String> clone = (ArrayList<String>) nomes.clone();
	clone.add("cc");
}

}[/code]

Falows,

Opa, hahaha, enquanto eu estava com a tela de responder aberta… hahaha, é, como o silveta disse, o Collections.copy também rola!

Só seguindo meu exemplo…

[code]public class TesteArrayCLone {
public static void main(String[] args) {
new TesteArrayCLone();
}

TesteArrayCLone() {
	ArrayList<String> nomes = new ArrayList<String>();
	nomes.add("aa");
	nomes.add("bb");
	balbla(nomes);
	
	
	for(String n: nomes) System.out.println(n);
}

private void balbla(List<String> nomes) {
	List<String> clone = new LinkedList<String>();
	Collections.copy(nomes, clone) ;
	
	clone.add("cc");
}

}[/code]

Victor, tentei fazer do geito que vc colocou no ultimo comentario mas nao deu certo nao.
E lancada uma exceção.

[quote=victor.godinho]Opa, hahaha, enquanto eu estava com a tela de responder aberta… hahaha, é, como o silveta disse, o Collections.copy também rola!

Só seguindo meu exemplo…

[code]public class TesteArrayCLone {
public static void main(String[] args) {
new TesteArrayCLone();
}

TesteArrayCLone() {
	ArrayList<String> nomes = new ArrayList<String>();
	nomes.add("aa");
	nomes.add("bb");
	balbla(nomes);
	
	
	for(String n: nomes) System.out.println(n);
}

private void balbla(List<String> nomes) {
	List<String> clone = new LinkedList<String>();
	Collections.copy(nomes, clone) ;
	
	clone.add("cc");
}

}[/code][/quote]

Collections.copy funciona para atributos não primitívos ou mutáveis? com dados primitivos ou imutáveis é tranquilo d+, basta fazer
List clone = new ArrayList(nomes);
só que quando o array guarda referências para outros objetos apenas as referências são copiadas, mas para dados primitivos funfa de boas.

sabem se o Collections.copy clona os objetos referenciados ou se apenas copia as referências?

Uma lista pode ser passada como parâmetro no construtor de outra como copia:

List<String> nomes = Arrays.asList(new String[] {"Vinicius", "Godoy", "Mendonça", "Pedro"}); List<String> copiaNomes = new LinkedList(nomes);

Porém, os objetos internamente não são copiados. Não deve ser problema se eles forem imutáveis (como Strings), mas pode ser uma dor de cabeça se forem.
É aí que entra a diferença do método Collections.clone. Ele tentará chamar o clone do conteúdo também.

[quote=ViniGodoy]Uma lista pode ser passada como parâmetro no construtor de outra como copia:

List<String> nomes = Arrays.asList(new String[] {"Vinicius", "Godoy", "Mendonça", "Pedro"}); List<String> copiaNomes = new LinkedList(nomes);

Porém, os objetos internamente não são copiados. Não deve ser problema se eles forem imutáveis (como Strings), mas pode ser uma dor de cabeça se forem.
É aí que entra a diferença do método Collections.clone. Ele tentará chamar o clone do conteúdo também. [/quote]

ok ViniGOdoy,
então se eu tenho a seguinte estrutura:

public abstract class Pessoa { int matricula; String nome; }

e duas classes Funcionario e Aluno que herdam Pessoa

[code]public class Funcionario extends Pessoa {
List projetos;
}

public class Aluno extends Pessoa {
List disciplinas;
}
[/code]

se eu não tiver o método clone() implementado em todas as classes e fizer Pessoa.clone() vou obter apenas as referências que das listas contidas em uma pessoa, certo?
agora, se todas essas classes (Projeto, Disciplica e Pessoa) implementarem clone(), quando eu usar Pessoa.clone() obterei uma cópia completa dos objetos e não apenas suas referências?

Não estava falando nada sobre herança. Se um pai é clonavel, os filhos tem que obrigatoriamente reimplementar o clone para dizer como serão copiados.

O que estava falando é da cópia dos objetos dentro da lista.

Ou seja, se você chamar Collections.copy, para as listas de funcionário e Disciplina, ele fará uma chamada ao clone de cada Disciplina e cada Projeto dentro da lista. Assim, a alteração de uma disciplina na nova lista não alterará a mesma disciplina na lista antiga.

Se você só usar o construtor, você terá uma nova lista, que aponta para as mesmas disciplinas ou projetos da lista antiga. Nesse caso, alterar uma disciplina alterará em todo lugar. Porém, adicionar ou remover novos elementos na lista clonada não irá adicionar ou remover elementos na lista original (pois a lista em si, foi copiada).

Conseguiu entender?

[quote=ViniGodoy]Não estava falando nada sobre herança. Se um pai é clonavel, os filhos tem que obrigatoriamente reimplementar o clone para dizer como serão copiados.

O que estava falando é da cópia dos objetos dentro da lista.

Ou seja, se você chamar Collections.copy, para as listas de funcionário e Disciplina, ele fará uma chamada ao clone de cada Disciplina e cada Projeto dentro da lista. Assim, a alteração de uma disciplina na nova lista não alterará a mesma disciplina na lista antiga.

Se você só usar o construtor, você terá uma nova lista, que aponta para as mesmas disciplinas ou projetos da lista antiga. Nesse caso, alterar uma disciplina alterará em todo lugar. Porém, adicionar ou remover novos elementos na lista clonada não irá adicionar ou remover elementos na lista original (pois a lista em si, foi copiada).

Conseguiu entender?[/quote]

ok ViniGodoy, acho que ficou claro.
em suma, se eu faço List<Projeto> clone = new ArrayList<Projeto>(listaAntiga); irá copiar apenas as referências.
se eu fizer Collections.copy(clone, listaAntiga); irá fazer uma cópia de cada objeto desde que os mesmos implementem clone(), caso contrário copiará apenas as referências, assim como no 1° caso, certo?

Exatamente.