124 votes

Éléments communs à deux listes

J'ai deux ArrayList objets avec trois entiers chacun. Je veux trouver un moyen de retourner les éléments communs des deux listes. Quelqu'un a-t-il une idée de la façon dont je peux y parvenir ?

185voto

BalusC Points 498232

Utilice Collection#retainAll() .

listA.retainAll(listB);
// listA now contains only the elements which are also contained in listB.

Si vous voulez éviter que les modifications soient affectées en listA alors vous devez en créer un nouveau.

List<Integer> common = new ArrayList<Integer>(listA);
common.retainAll(listB);
// common now contains only the elements which are contained in listA and listB.

0 votes

RetainAll renvoie une nouvelle liste ? J'ai essayé de stocker la sortie de retain dans une nouvelle liste, quelque chose comme tempList.addAll(listA.retainAll(listB)) ; mais cela ne fonctionne pas.

1 votes

Comme répondu dans le lien derrière Collection#retainAll() et les commentaires dans les extraits de code, non, ce n'est pas le cas. Les changements sont reflétés dans la liste sur laquelle vous appelez la méthode.

0 votes

Le problème est que la liste common est initialisée avec une taille de 3, puis vous essayez de changer sa taille en retournant seulement un ou deux éléments. J'essaie ce que vous suggérez et cela me renvoie une exception hors limites.

44voto

Pablo Santa Cruz Points 73944

Vous pouvez utiliser les opérations d'intersection de jeux avec votre ArrayList objets.

Quelque chose comme ça :

List<Integer> l1 = new ArrayList<Integer>();

l1.add(1);
l1.add(2);
l1.add(3);

List<Integer> l2= new ArrayList<Integer>();
l2.add(4);
l2.add(2);
l2.add(3);

System.out.println("l1 == "+l1);
System.out.println("l2 == "+l2);

List<Integer> l3 = new ArrayList<Integer>(l2);
l3.retainAll(l1);

    System.out.println("l3 == "+l3);

Maintenant, l3 ne devraient avoir que des éléments communs entre l1 y l2 .

CONSOLE OUTPUT
l1 == [1, 2, 3]
l2 == [4, 2, 3]
l3 == [2, 3]

7 votes

Notez que de cette façon, les changements sont reflétés dans l2 également. Vous vouliez probablement dire List<Integer> l3 = new ArrayList<Integer>(l2); à la place.

0 votes

Le problème devient un peu plus compliqué si disons que l1 a 2 d'un élément et l2 a 3 de ce même élément. retainAll returns met 3 de cet élément dans l3 même s'il n'est contenu que deux fois dans l1.

42voto

Pourquoi réinventer la roue ? Utilisez Collections Commons :

CollectionUtils.intersection(java.util.Collection a, java.util.Collection b)

24voto

Robby Cornelissen Points 11222

Utilisation de Java 8 Stream.filter() en combinaison avec List.contains() :

import static java.util.Arrays.asList;
import static java.util.stream.Collectors.toList;

/* ... */

List<Integer> list1 = asList(1, 2, 3, 4, 5);
List<Integer> list2 = asList(1, 3, 5, 7, 9);

List<Integer> common = list1.stream().filter(list2::contains).collect(toList());

4 votes

Les conteneurs semblent être une opération O(n), qui serait appelée n fois, à moins que le compilateur ne fasse quelque chose d'intelligent. Quelqu'un sait-il si l'opération ci-dessus s'exécute en temps linéaire ou quadratique ?

1 votes

Ce serait une opération n*n !

2 votes

Note au lecteur : En Java 16+, remplacez [.collect( Collectors.toList() )](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/stream/Collectors.html#toList()) avec plus court [.toList()](https://docs.oracle.com/en/java/javase/16/docs/api/java.base/java/util/stream/Stream.html#toList()) (une nouvelle méthode sur Stream ).

7voto

Rajeev Ranjan Points 444
List<Integer> listA = new ArrayList<>();
    listA.add(1);
    listA.add(5);
    listA.add(3);
    listA.add(4);   

List<Integer> listB = new ArrayList<>();
    listB.add(1);
    listB.add(5);
    listB.add(6);
    listB.add(7);
System.out.println(listA.stream().filter(listB::contains).collect(Collectors.toList()));

Java 1.8 Stream API Solutions

Sortie [1, 5]

0 votes

-Amélioration : nous pouvons définir la liste comme suit : List<Integer> listA = asList(1, 5, 3, 4) ; List<Integer> listB = asList(1, 5, 6, 7) ;

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X