Pergunta

Eu tenho alguns dados armazenados como ArrayList. E quando eu quiser fazer um backup desses dados, java delimita dois objetos para sempre. Que significa que quando eu mudar os valores nos dados ArrayList estas mudanças vêm para backup. Eu tentei copiar valores de dados separadamente para fazer backup no circuito, tentou data.clone() método de uso - nada ajuda

.
Foi útil?

Solução

Eu acho que você precisa .clone() os objetos individuais. Clonagem do ArrayList não é "profundo"; ele só irá clonar as referências ao objeto.

Outras dicas

A sua pergunta não é muito clara. Se você clone () um ArrayList, o clone não será modificada se você alterar o conteúdo do original (ou seja, se você adicionar ou elementos remover), mas é uma "cópia superficial" por isso, se você alterar os objetos reais no original eles vão também ser alterado no clone.

Se você quiser fazer uma "cópia profunda", para que as alterações aos objetos reais não vai afetar os backups de-los no clone, então você precisa criar um novo ArrayList e depois passar o original e para cada elemento, cloná-lo para o novo. Como em

ArrayList backup = new ArrayList();
for (Object obj : data)
   backup.add(obj.clone());

Estou assumindo data é o nome do ArrayList você queria backup. Se assim for, você deve saber que clone não é profunda - ele só cria uma cópia do objeto sobre o qual ela é invocada, que neste caso é a lista. Se fosse um clone profundo, seria encher a nova lista com clones dos objetos nele.

Uma vez que não é profundo, se você alterar os objetos a lista contém, em seguida, a lista de backup irá mostrar essas mudanças, bem como, uma vez que está contendo os mesmos objetos. A única vez que você não verá alterações na cópia de segurança depois de alterar a lista de "atual" é quando você adicionar ou remover objetos da lista atual.

Algumas classes podem substituir clone ser profundo, mas não todos. Em geral, não é algo que você pode confiar. Ao criar uma cópia de backup de coleções Java, lembre-se de qualquer clone os objetos contidos, bem como, ou lidar apenas com coleções de objetos imutáveis.

Todos estes processos fazer cópias rasas. Se você está mudando as propriedades dos objetos com na matriz, as duas matrizes têm referências para a mesma instância.

List org = new java.util.ArrayList();
org.add(instance)
org.get(0).setValue("org val");
List copy = new java.util.ArrayList(org);
org.get(0).setValue("new val");

copy.get(0).getValue() voltará "new val", mas também porque org.get(0) e regresso copy.get(0) exatamente o mesmo exemplo. Você tem que executar uma cópia profunda assim:

List copy = new java.util.ArrayList();
for(Instance obj : org) {
    copy.add(new Instance(obj)); // call to copy constructor
}

Depende do que você precisa. cópia superficial (itens na lista são referências para o mesmo como no original):

ArrayList backup = new ArrayList(mylist.size());
backup.addAll(mylist);

cópia profunda (itens são cópias também):

ArrayList backup = new ArrayList(mylist.size());
for(Object o : mylist) {
    backup.add(o.clone());
}

Parece (se eu interpretar a sua pergunta corretamente, é um pouco difícil) como você não está copiando os dados que você está se referindo em seu ArrayList para o seu backup; você está copiando a referência.

É difícil dizer exatamente como resolver seu problema sem saber o seu tipo de dados é que você está armazenando / backup, mas apenas a certeza de que você está copiando os elementos dos dados contidos dentro do ArrayList. Isso significaria, entre outras coisas, fazer coisas como realizar um clone () sobre os elementos da lista, mas não no ArrayList (porque isso vai criar uma nova lista clonados com cópias das referências aos mesmos objetos).

Quanto ao problema da clonagem, uma vez que eu resolvi isso serialização toda a coleção em uma corda, em seguida, serialização-lo de volta para um novo objeto. Isso força você a fazer todos os seus objetos serializado e tomar quando dois objetos realmente quer fazer referência a um único terceiro objeto, mas pode ser um equilíbrio muito bom de simplicidade e utilidade.

Na verdade, eu não tentei isso, mas você provavelmente poderia usar um tubo para serialize dentro e fora ao mesmo tempo exato para que você não está armazenando 3 cópias na memória (se é uma enorme coleção)

Aqui é um pleno funcionamento ArrayList classe de backup que verifica se o ArrayList já existe. Basicamente é apenas um loop for de bicicleta pela lista e manualmente adicioná-los à nova lista.

import java.util.ArrayList;

public class Snapshot {
    private ArrayList<Integer> dataBackup;

    public Snapshot(ArrayList<Integer> data)
    {
        dataBackup = new ArrayList<Integer>();
        for(int i = 0; i < data.size(); i++)
        {
            dataBackup.add(data.get(i));
        }
    }

    public ArrayList<Integer> restore()
    {
        return dataBackup;
    }

    public static void main(String[] args)
    {
        ArrayList<Integer> list = new ArrayList<Integer>();
        list.add(1);
        list.add(2);

        Snapshot snap = new Snapshot(list);

        list.set(0, 3);
        list = snap.restore();

        System.out.println(list); // Should output [1, 2]

        list.add(4);
        list = snap.restore();

        System.out.println(list); // Should output [1, 2]
    }
}

Eu não tentei ainda, mas acho que Collections.copy vai fazer isso.

[EDIT] Agora, eu tentei:

static String GetRandomString(int length)
{
  UUID uuid = UUID.randomUUID();
  return uuid.toString().substring(0, length);  
}

public static void main(String[] args)
{
  ArrayList<String> al = new ArrayList<String>(20);
  for (int i = 0; i < 10; i++)
  {
    al.add(GetRandomString(7));
  }
  ArrayList<String> cloneArray = new ArrayList<String>(al);
  Collections.copy(cloneArray, al);
  System.out.println(al);
  System.out.println(cloneArray);
  for (int i = 9; i >= 0; i -= 2)
  {
    al.remove(i);
  }
  System.out.println(al);
  System.out.println(cloneArray);
}

Você poderia escrever um objeto que envolve dois ArrayLists. Escreva qualquer coisa-lo para que ele adiciona, remove e modifica dados em ambos ao mesmo tempo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top