Question

J'ai des données stockées sous ArrayList . Et lorsque je veux sauvegarder ces données, Java limite deux objets pour toujours. Ce qui signifie que lorsque je modifie des valeurs dans des données ArrayList , ces modifications sont sauvegardées. J'ai essayé de copier les valeurs des données séparément pour sauvegarder dans la boucle, d'utiliser la méthode data.clone () & # 8212; rien n'y fait.

Était-ce utile?

La solution

Je pense que vous devez .clone () les objets individuels. Le clonage de la ArrayList n’est pas "profond" ;; il ne fera que cloner les références à l'objet.

Autres conseils

Votre question n'est pas très claire. Si vous clonez () une ArrayList, le clone ne sera pas modifié si vous modifiez le contenu de l'original (c'est-à-dire si vous ajoutez ou supprimez des éléments), mais il s'agit d'une "copie superficielle". Par conséquent, si vous modifiez les objets réels dans l'original, ils seront également modifiés dans le clone.

Si vous souhaitez créer une "copie complète" de sorte que les modifications apportées aux objets réels n'affectent pas leurs sauvegardes dans le clone, vous devez créer un nouveau tableau ArrayList, puis consulter celui d'origine. chaque élément, clonez-le dans le nouveau. Comme dans

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

Je suppose que data est le nom du ArrayList que vous souhaitez sauvegarder. Si tel est le cas, vous devez savoir que clone n'est pas deep - il crée uniquement une copie de l'objet sur lequel il est appelé, qui est dans ce cas la liste. S'il s'agissait d'un clone profond, la nouvelle liste serait remplie de clones des objets qu'il contient.

Etant donné que ce n'est pas profond, si vous modifiez les objets contenus dans la liste, la liste de sauvegarde affichera également ces modifications, car elle contient les mêmes objets. La seule fois où vous ne verrez pas de modifications dans la sauvegarde après avoir modifié le paramètre "en cours". La liste correspond au moment où vous ajoutez ou supprimez des objets de la liste actuelle.

Certaines classes peuvent remplacer le code clone par Deep, mais pas toutes. En général, ce n'est pas une chose sur laquelle vous pouvez compter. Lors de la création d'une copie de sauvegarde des collections Java, n'oubliez pas de cloner également les objets contenus ou de ne traiter que des collections d'objets immuables.

Tous ces processus font des copies superficielles. Si vous modifiez les propriétés des objets contenus dans le tableau, les deux tableaux contiennent des références à la même instance.

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 () renverra " nouveau val & également car org.get (0) et copy.get (0) renvoie exactement la même instance. Vous devez effectuer une copie en profondeur comme suit:

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

Cela dépend de ce dont vous avez besoin. Copie peu profonde (les éléments de la liste font référence à la même chose que dans l’original):

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

Copie profonde (les éléments sont également des copies):

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

Il semble (si j’interprète correctement votre question; c’est un peu difficile) que vous ne copiez pas les données dont vous parlez dans votre ArrayList dans votre sauvegarde; vous copiez la référence.

Il est difficile de dire exactement comment résoudre votre problème sans connaître le type de données que vous stockez / sauvegardez, mais assurez-vous simplement de copier les éléments des données contenues dans ArrayList. Cela impliquerait, entre autres choses, de faire des choses comme effectuer un clone () sur les éléments de la liste, mais pas sur ArrayList (car cela créerait une nouvelle liste clonée avec des copies des références aux mêmes objets).

En ce qui concerne le problème du clonage, une fois résolu le problème en sérialisant la collection entière dans une chaîne, puis en le sérialisant dans un nouvel objet. Cela vous oblige à rendre tous vos objets sérialisables et à prendre lorsque deux objets veulent vraiment référencer un seul troisième objet, mais cela peut constituer un assez bon équilibre entre simplicité et utilité.

En fait, je n'ai pas essayé cela, mais vous pouvez probablement utiliser un tuyau pour effectuer une sérialisation d'entrée et de sortie au même moment, de manière à ne pas stocker 3 copies en mémoire (s'il s'agit d'une énorme collection)

Voici une classe de sauvegarde ArrayList entièrement fonctionnelle qui vérifie si la liste ArrayList existe déjà. Fondamentalement, il s’agit simplement de parcourir en boucle la liste et de les ajouter manuellement à la nouvelle liste.

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]
    }
}

Je ne l'ai pas encore essayé, mais je pense que Collections.copy le fera.

[EDIT] Maintenant, j'ai essayé:

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);
}

Vous pouvez écrire un objet qui encapsule deux ArrayLists. N'importe quoi, écrivez-le pour qu'il ajoute, supprime et modifie des données simultanément.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top