2010-04-30 2 views
1

Si j'exécute cette opération sur List<Integer> par exemple, cela fonctionne comme prévu (supprime les 5 premiers éléments), mais quand je l'exécute sur une liste de mes objets, rien ne se passe (la liste reste la même).Java: Pourquoi subList (0, 5) .clear() ne fonctionne pas sur mes objets?

list.subList(0, 5).clear(); 

Ma classe est un POJO qui ne met pas en œuvre equals ou hashCode, si cela importe.

MISE À JOUR: L'implémentation que j'utilise est ArrayList, qui est renvoyée à partir de la requête Hibernate. Il n'y a rien à montrer, vraiment. La sous-liste ne renvoie pas une liste vide.

Voici un exemple pour ceux qui ne beleive pas que cela fonctionne sur une liste de Entiers:

List<Integer> testList = new ArrayList<Integer>(); 
    for(int i=0;i<10;i++) { 
     testList.add(i); 
    } 
    testList.subList(0, 5).clear(); 
    for(int i=0;i<testList.size();i++) { 
     System.out.print(testList.get(i)+" "); 
    } 

Le résultat est 5 6 7 8 9

MAJ2: En fait, tout fonctionne comme prévu, don Je ne sais pas comment je ne pouvais pas voir ça (j'ai été troublé par le nombre de résultats). Désolé pour fausse alerte :) Cette question pourrait être supprimée.

+1

Pourriez-vous poster un petit extrait de code montrant le problème? Cela devrait vraiment fonctionner. –

+1

Maintenant, que diriez-vous du code qui échoue? Le code réussi est difficile à déboguer ;-) –

+0

Merde car il s'avère que cela fonctionnait depuis le début, par mauvais. Désolé :) – serg

Répondre

4

Il fonctionne sur ma machine tm

import java.util.*; 
import static java.lang.System.out; 

class SubListExample { 
    public static void main(String [] args) { 
     List<RandomObject> testList = new ArrayList<RandomObject>(); 
     for(int i=0;i<10;i++) { 
      testList.add(new RandomObject()); 
     } 

     System.out.println("Before: " + testList); 
     testList.subList(0, 5).clear(); 
     System.out.println("After: "+ testList); 
    } 
} 
class RandomObject { 
    static Random generator = new Random(); 
    int id = generator.nextInt(100); 
    public String toString(){ 
     return "ro("+id+")"; 
    } 
} 

Produit:

$ java SubListExample 
Before: [ro(68), ro(97), ro(48), ro(45), ro(43), ro(69), ro(45), ro(8), ro(88), ro(40)] 
After: [ro(69), ro(45), ro(8), ro(88), ro(40)] 

Ainsi, le problème est pas ArrayList ni dans vos objets.

Je ne pense pas que Hibernate renvoie une ancienne plaine ArrayList (peut-être qu'il fait)

Essayez d'imprimer

System.out.println("That hibernate list.class.name = " 
     + listReturnedByHibernate.getClass().getName()); 

Et laissez-nous savoir si elle est en fait une ArrayList

3

modifier - On dirait que je me suis trompé, mais en laissant ma réponse originale ici de toute façon:

Etes-vous sûr que cela fonctionne avec un List<Integer>? Ça ne devrait pas. La méthode subList() renvoie un List distinct. Si vous supprimez des éléments de cette liste, cela ne devrait pas affecter la liste d'origine. Les API docs pour List.subList() dire ceci:

Renvoie une vue de la partie de cette liste entre les parties spécifiées fromIndex, y compris, et toIndex, exclusif. (Si fromIndex et toIndex sont égaux, la liste retournée est vide.) La liste retournée est sauvegardée par cette liste, donc les changements non structurels dans la liste retournée sont reflétés dans cette liste, et vice-versa.

L'effacement d'une liste n'est pas un changement non structurel; seuls les changements dans les éléments de la liste sont des changements non structurels.

Cela n'a rien à voir si votre POJO a ou non des méthodes equals ou hashCode.

modifier - Je viens d'essayer avec un ArrayList et il ne fonctionne (non seulement avec Integer, mais aussi avec mon propre objet comme élément de la liste).

+0

Je pensais que dans un premier temps, mais la section suivante du javadoc donne un exemple spécifique: "Cette méthode élimine le besoin d'opérations de plage explicites (du type qui existe généralement pour les tableaux) Toute opération qui attend une liste peut être utilisée comme une opération de plage en transmettant une vue subList au lieu d'une liste entière (par exemple, l'idiome suivant supprime une gamme d'éléments d'une liste: 'list.subList (from, to) .clear();' ". Il dit des changements non structurels là parce que les changements structurels ne fonctionnent pas vice-versa; si vous modifiez la structure sauvegardée, la copie ne change pas, mais l'inverse fonctionne –

+0

Hmm, vous avez raison. Maintenant, je ne suis pas sûr si cela est supposé fonctionner correctement avec n'importe quel type de 'List' ou pas. – Jesper

+0

Il est dans le doc pour la classe List, donc il devrait; il ne devrait pas importer si le générique est Integer ou SomeRandomObject –

0

Deux choses que je peux penser sont:

  1. list.sublist(0, 5) retourne une liste vide, donc .clear() ne fait rien.

  2. Pas sûr du fonctionnement interne de la mise en œuvre de la liste que vous utilisez (ArrayList, LinkedList, etc), mais ayant la mise en œuvre equals et hashCode peut être important. J'ai eu un problème simiarl avec Maps, où HashMap a vraiment besoin de l'implémentation de hashCode.

+3

Les collections basées sur des hachages telles que 'HashMap' et' HashSet' nécessitent une méthode 'equals' et' hashCode' appropriée, mais 'ArrayList',' LinkedList' etc. n'utilisent pas ces méthodes. – Jesper

0

Avez vous avez essayé de créer un List de vos objets manuellement et de faire la même chose (sans Hibernate)? Il me semble possible que cela ait à voir avec le chargement paresseux des données de Hibernate ... si vous n'avez pas lu les données dans le List retourné, il n'a peut-être pas encore été chargé (puisque les sous-listes ne sont que des vues). Dans ce cas, il est possible que clear ne fasse rien.

0

Est-il possible que la liste retournée par Hibernate ne soit pas modifiable? c'est-à-dire enveloppé par Collections.unmodifiableList()

+1

Mais alors il devrait lancer une exception java.lang.UnsupportedOperationException – leonbloy

Questions connexes