2010-08-21 5 views
0

J'ai une liste dans un objet de données dans Java qui héberge des données extraites d'une base de données, qu'il s'agisse de lignes multiples ou simples. Je récupère la liste du BO et la jette dans une liste temporaire afin que je puisse itérer dessus pour extraire des données. Quand je vérifie juste la taille de la liste après avoir fait la première affectation, tout se passe bien, mais quand j'essaie de parcourir la liste dans une boucle for, sa taille diminue. Je testais avec deux lignes de données dans la liste, mais dans les toilettes, sa taille était toujours une. Et la partie amusante est, j'ai utilisé cette logique dans beaucoup d'endroits plusieurs fois, mais dans ce processus d'affaires dans lequel j'écrivais ceci, il s'est comporté très erratiquement. Tout le monde a des pistes à ce sujet? Voici un exemple de codeComportement erratique des listes en Java

List temp = new ArrayList(); 

temp = dummyBO.getList(0) // Retrieves the List at index 0 from the BO 

//Imagine the list has 2 rows of data. This prints the size as 2 
System.out.println("size: "+temp.size()); 

System.out.println("Contents: "+temp.get(0); 
System.out.println("Contents: "+temp.get(1); 

//This is where the List starts behaving erratically 

**for(int i=0;i<temp.size();i++){ 
    System.out.println("size: "+temp.size()); //here the size is displayed as 1 
    System.out.println("Contents: "+temp.get(i); // here only the data at index 0 is shown 
}** 

P.S. Ce code java est écrit dans la section d'extrait dans IBM IFD 6.1

+0

Vous ne devez pas utiliser les types bruts dans le nouveau code: http://stackoverflow.com/questions/2770321/what-is-a-type-et-type-et-pourquoi- ne devrions-nous pas utiliser – polygenelubricants

+0

Qu'est-ce que dummyBO? .getList (0) vraiment retreiving? Une ArrayList réelle, ou quelque chose d'autre, par ex. une liste d'hibernate ou une autre technologie d'accès aux données? Êtes-vous sûr qu'il n'y a pas par ex. d'autres threads aussi déconner avec ce que dummyBO.getList (0) retreives? – nos

Répondre

2

Je suppose que ce

temp = dummyBO.getList(0) 

récupère une référence à une liste, pas une copie. Donc, tout ce qui vous a fourni cette référence serait libre de modifier cette liste. Avez-vous besoin de prendre une copie défensive de cette liste?

+0

Salut Brian, pourriez-vous élaborer sur la copie défensive que vous avez mentionnée? – Aditya

3

Vous avez dit:

je récupère la List de la BO et le jeter dans une liste temporaire

Et votre extrait dit:

// original snippet 
List temp = new ArrayList();  
temp = dummyBO.getList(0); 

Il est impossible de dire avec une certitude absolue, mais c'est une odeur de code, et en toute probabilité, le bogue qui cause votre problème.

La partie malodorante est le fait que vous avez créé un new ArrayList, mais il devient immédiatement une poubelle. Cet extrait ne remplit pas cette ArrayList avec les éléments de la liste dummyBO. Il définit temp pour faire référence à un objet nouvellement créé, mais il lâche ensuite cet objet pour se référer à autre chose entièrement. Rappelez-vous que = pour les objets est simplement une affectation de référence en Java; il ne peut PAS être surchargé pour faire quelque chose de différent.

Peut-être que vous voulez quelque chose comme ceci:

// possible fix #1 
List temp = new ArrayList(dummyBO.getList(0)); 

Ce sera en fait de créer un new ArrayList et peuplant cette liste avec les éléments de la liste que vous obtenez de dummyBO. Cela utilise le constructeur ArrayList(Collection), qui itère sur le Collection et ajoute ses éléments à la liste.

Sinon, vous pouvez aussi faire quelque chose comme ceci:

// possible fix #2 
List temp = new ArrayList(); 
temp.addAll(dummyBO.getList(0)); 
+0

Salut, merci beaucoup pour vos suggestions. Cela a beaucoup de sens. Je vais essayer cela et revenir sur ce qui a fonctionné. :) – Aditya

0

Comme disent les autres réponses, vous devez copier le contenu de la liste.

Mais vos problèmes sont plus profonds que cela. Il est clair que un autre thread change le contenu de la liste. Le simple fait de copier la liste renvoyée par getList(0) ne sera pas fiable. L'autre thread peut changer la liste pendant que vous le copiez!

Au lieu de cela, vous avez besoin de changer la méthode getList(int) afin que il crée la copie de la liste, et elle le fait maintenant un verrou pour arrêter la liste étant changé alors qu'il est en cours de copie.

EDIT

La copie de la liste peut être faite en utilisant le constructeur de copie; par exemple. utilisez new ArrayList(someList) selon la réponse de @polygenelubricants. Mais il n'y a pas de réponse simple à la manière dont vous verrouillez la liste pour arrêter la modification de la liste pendant sa copie. Cela dépend de quoi d'autre accède et met à jour la liste ... et comment.

+0

Salut Stephen, pouvez-vous s'il vous plaît dites-moi, comment réaliser la création de la copie et le verrouillage de la liste? Merci beaucoup pour votre merveilleuse suggestion :) – Aditya

Questions connexes