[java] supp les doublures ds 2 obj ArrayList

Fermé
amine33700 - 17 nov. 2008 à 00:10
Marco la baraque Messages postés 996 Date d'inscription vendredi 9 mai 2008 Statut Contributeur Dernière intervention 5 novembre 2009 - 17 nov. 2008 à 18:00
Bonsoir,

je travaille sur deux objets l1 et l2 de type ArrayList : je veux supprimer les doublures (les elements en communs) dans l1 et l2 : la suppression sera appliquée sur une des deux listes ici l1 ,pour cela j'ai ecrit une classe test contenant la methode "elim_doublure":
*********************************************************
import java.util.ArrayList;


public class Test {


ArrayList lz = new ArrayList();
ArrayList le = new ArrayList();
public ArrayList elim_doubure(ArrayList l1,ArrayList l2)
{

for(int i = 0; i <l2.size(); i++){
for(int j = 0; j <l1.size(); j++)
{
if(l2.get(i) == l1.get(j))
l1.remove(i);

}

}
return l1;

}

}
*******************************************************

puis j'ai appele elim_doublure dans "main" pour afficher le resultat de la suppression :


import java.util.ArrayList;


public class zx {
public static void main(String[] args) {
Test k =new Test();
ArrayList L1 = new ArrayList();
ArrayList L2 = new ArrayList();
Test t = new Test();
al.add(12);
L1.add("Une!");
L1.add(12.20f);
L1.add('d');
L2.add(12);
L2.add('b');
L2.add('d');
L2.add("Une!");

k.elim_doubure(L1, L2);
System.out.println("///////////////////////////////////////////////////////////////////////////////////////////////////////");
for(int i1 = 0; i1 <L2.size(); i1++)
{
System.out.println("L2"+L2.get(i1));
}
System.out.println("///////////////////////////////////////////////////////////////////////////////////////////////////////");
for(int i = 0; i <L1.size(); i++)
{
System.out.println("L1"+L1.get(i));
}

}

}

*********************************************************************

le pb ici est qu' en executant le pg eclipse m'affiche :

Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 3, Size: 2
at java.util.ArrayList.RangeCheck(Unknown Source)
at java.util.ArrayList.remove(Unknown Source)
at Test.elim_doubure(Test.java:16)
at zx.main(zx.java:19)
**********************************************************************************

est ce que klk1 a une idee ou une solution de ce pb
A voir également:

5 réponses

Marco la baraque Messages postés 996 Date d'inscription vendredi 9 mai 2008 Statut Contributeur Dernière intervention 5 novembre 2009 329
17 nov. 2008 à 00:17
Bonsoir,
public ArrayList elim_doubure(ArrayList l1,ArrayList l2)
{

for(int i = 0; i <l2.size(); i++){
for(int j = 0; j <l1.size(); j++)
{
if(l2.get(i) == l1.get(j))
l1.remove(j);

}

}
return l1;

} 


Cordialement,
0
Hello,

Je ne suis pas sur que ton algo soit très optimisé, mais bon...

essaye de rajouter un break; après ton l1.remove(i); donc tu aurais :

if(l2.get(i) == l1.get(j))
{
l1.remove(i);
break;
}


par contre, ton test if ci-dessus, ne devrait pas fonctionner... on utilise pas de == pour comparer des string, mais on utilise :

monString1.Equals(monString2)


pour que ta méthode fonction bien, tu devrais mettre qu'un type de donnés et pas mélanger des char avec des string. l'idéal serait de typer t arraylist :

// j'ai un blanc, il me semble qu'on fait comme ceci, c'est pour forcer une arraylist qui peut uniquement
//contenir des string
ArrayList<String> L1 = new ArrayList<String>();
0
Petite correction : l1.remove(j);
0
Marco la baraque Messages postés 996 Date d'inscription vendredi 9 mai 2008 Statut Contributeur Dernière intervention 5 novembre 2009 329
17 nov. 2008 à 16:01
Bonjour,
Concernant la méthode equals(), il faut évidemment l'utiliser dès que tu veux utiliser cet algorithme pour faire autre chose que de la comparaison de types primitifs (et donc par exemple ici tu utilises des Strings, donc des objets, donc il faut que tu utilises equals).

@Sims : il ne faut pas mettre de break dans la boucle for. On peut imaginer que la liste l1 possède plusieurs fois le même élément, dans ce cas on voudra le supprimer à chaque fois.

pour que ta méthode fonction bien, tu devrais mettre qu'un type de donnés et pas mélanger des char avec des string. l'idéal serait de typer t arraylist :
Ca par contre c'est faux. Faire un ArrayList<Object> lui permettra d'avoir un algo générique. La méthode equals retournera false s'il essaie de comparer des carottes avec des navets, donc c'est le comportement souhaité.

Par contre, il faudra utiliser des instances d'objet tout le temps :
des Integer au lieu d'utiliser des int
des Character au lieu des char
...

Cordialement,
0
@Marco: effectivement pour le break, tu n'as pas tort...

Par contre, je ne veux pas dire de bêtise, mais l'algo n'est pas correct, au niveau de la suppression des éléments...

Je m'explique...

array1 = {"test", "test", "fin1"} ;
array2 = {"test", "fin2"} ;

je récupére le premier élément du 2ème array "test", je le compare au premier array ce qui donne :

j=0 => "test".Equals("test") => true => delete
j=1 => "fin".Equals("test") => false => rien
fin boucle for

en fait, dans l'exemple ci-dessus le mot "test" devrait être supprimé 2 fois, mais comme on fait un remove, tous les indices sont décalé et par conséquent, certain élément ne seront pas testé/comparé... et d'ailleur la boucle sera réduite...
0
togodo Messages postés 148 Date d'inscription vendredi 19 septembre 2008 Statut Membre Dernière intervention 19 août 2009 8
17 nov. 2008 à 17:53
Je confirme l'histoire, l'algorithme est mauvais.Il faut rajouté un i--; dans le if() après le remove :
if()
{
.remove...
i--;
}
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Marco la baraque Messages postés 996 Date d'inscription vendredi 9 mai 2008 Statut Contributeur Dernière intervention 5 novembre 2009 329
17 nov. 2008 à 17:43
Si, l'algo est correct, car il a deux boucles imbriquées : pour chaque i il va parcourir tous les j.
Après, je suis entièrement d'accord pour dire que ce n'est pas optimisé du tout, mais je pense que ça fonctionne.

Cordialement,
0
togodo Messages postés 148 Date d'inscription vendredi 19 septembre 2008 Statut Membre Dernière intervention 19 août 2009 8
17 nov. 2008 à 17:56
Si le remove se fait sur l'élément i=2 , l'élément i=3 devient en fait l'élément i=2, et est "sauter".
C'est banal.
0
Marco la baraque Messages postés 996 Date d'inscription vendredi 9 mai 2008 Statut Contributeur Dernière intervention 5 novembre 2009 329 > togodo Messages postés 148 Date d'inscription vendredi 19 septembre 2008 Statut Membre Dernière intervention 19 août 2009
17 nov. 2008 à 18:00
Au temps pour moi.

Cordialement,
0