Existe-t-il des méthodes pour le faire? Je cherchais mais je n'en trouvais pas.
Une autre question: j'ai besoin de ces méthodes pour pouvoir filtrer les fichiers. Certains sont des AND
filtres et d'autres sont des OR
filtres (comme dans la théorie des ensembles), je dois donc filtrer en fonction de tous les fichiers et des ArrayLists unite / intersecte qui contiennent ces fichiers.
Dois-je utiliser une structure de données différente pour contenir les fichiers? Y a-t-il autre chose qui offrirait une meilleure exécution?
java
list
union
intersection
yotamoo
la source
la source
Vector
? Cette classe est déconseillée depuis Java 1.2.Vector
est celui des interactions entre threads, mais il existe également des structures de données plus sûres pour ces cas d'utilisation. Voir aussi cette question . Toute bibliothèque encore utiliséeVector
en 2016 est très suspecte à mon avis.Réponses:
Voici une implémentation simple sans utiliser de bibliothèque tierce. Le principal avantage par rapport à
retainAll
,removeAll
etaddAll
c'est que ces méthodes ne modifient pas les listes d'origine entrées dans les méthodes.la source
HashSet
forintersection
pour que les performances moyennes des cas soient O (n) au lieu de O (n ^ 2).Collection (donc ArrayList également) ont:
Utilisez une implémentation List si vous acceptez les répétitions, une implémentation Set si vous ne le faites pas:
la source
HashSet
place.addAll()
est l'union des listes; il s'agit simplement de concaténer la deuxième liste à la fin de la première. Une opération d'union éviterait d'ajouter un élément si la première liste le contient déjà.Ce message est assez ancien, mais c'était néanmoins le premier à apparaître sur Google lors de la recherche de ce sujet.
Je veux donner une mise à jour en utilisant des flux Java 8 faisant (essentiellement) la même chose en une seule ligne:
Si quelqu'un a une solution meilleure / plus rapide, faites-le moi savoir, mais cette solution est une belle ligne unique qui peut être facilement incluse dans une méthode sans ajouter une classe / méthode d'aide inutile tout en conservant la lisibilité.
la source
Set
puis utilisez lacontains
méthode de l'ensemble . Tout dans la vie ne doit pas être fait avec des flux.l'union sera
removeAll
et alorsaddAll
.Pour en savoir plus, consultez la documentation de la collection (ArrayList est une collection) http://download.oracle.com/javase/1.5.0/docs/api/java/util/Collection.html
la source
retainAll()
etremoveAll()
sont des opérations O (n ^ 2) sur des listes. On peut faire mieux.retainAll
sur {1, 2, 2, 3, 4, 5} sur {1, 2, 3} donne {1, 2, 2, 3}. Ne devrait-il pas être {1, 2, 3} pour être l'intersection?Unions et intersections définies uniquement pour les ensembles, pas pour les listes. Comme vous l'avez mentionné.
Vérifiez la bibliothèque de goyave pour les filtres. La goyave fournit également de véritables intersections et unions
la source
Vous pouvez utiliser
CollectionUtils
depuis apache commons .la source
La solution marquée n'est pas efficace. Il a une complexité temporelle O (n ^ 2). Ce que nous pouvons faire est de trier les deux listes et d'exécuter un algorithme d'intersection comme celui ci-dessous.
Celui-ci a une complexité de O (n log n + n) qui est en O (n log n). L'union se fait de la même manière. Assurez-vous simplement de faire les modifications appropriées sur les instructions if-elseif-else.
Vous pouvez également utiliser des itérateurs si vous le souhaitez (je sais qu'ils sont plus efficaces en C ++, je ne sais pas si cela est également vrai en Java).
la source
contains()
en boucle (comme le suggère Devenv) prendrait un temps O (n + m). Le tri est inutilement compliqué et prend O (n log n + m log n + n) temps. Certes, cela se réduit à O (n log n) temps, mais c'est encore pire que le temps linéaire, et beaucoup plus complexe.Je pense que vous devriez utiliser un
Set
pour contenir les fichiers si vous voulez faire une intersection et une union sur eux. Ensuite, vous pouvez utiliser la classe Sets de Guava pour faire , et filtrer par a également. La différence entre ces méthodes et les autres suggestions est que toutes ces méthodes créent des vues paresseuses de l'union, de l'intersection, etc. des deux ensembles. Apache Commons crée une nouvelle collection et y copie des données. modifie l'une de vos collections en en supprimant des éléments.union
intersection
Predicate
retainAll
la source
Voici une façon de faire une intersection avec des flux (rappelez-vous que vous devez utiliser java 8 pour les flux):
Un exemple de listes de types différents. Si vous avez une relation entre foo et bar et que vous pouvez obtenir un bar-object de foo, vous pouvez modifier votre flux:
la source
J'ai trouvé ListUtils très utile pour ce cas d'utilisation.
Utilisez ListUtils de org.apache.commons.collections si vous ne souhaitez pas modifier la liste existante.
ListUtils.intersection(list1, list2)
la source
Vous pouvez utiliser commons-collections4 CollectionUtils
la source
Dans Java 8, j'utilise des méthodes d'aide simples comme celle-ci:
la source
Si les objets de la liste sont hachables (c'est-à-dire ont un hashCode décent et une fonction égale), l'approche la plus rapide entre les tables env. size> 20 consiste à construire un HashSet pour la plus grande des deux listes.
la source
Je travaillais également sur une situation similaire et je suis arrivé ici pour chercher de l'aide. J'ai fini par trouver ma propre solution pour les tableaux. ArrayList AbsentDates = new ArrayList (); // Stockera Array1-Array2
Remarque: publiez ceci si cela peut aider quelqu'un à accéder à cette page pour obtenir de l'aide.
la source
Intersection de deux listes d'objets différents basés sur une clé commune - Java 8
la source
JDK8 + (probablement la meilleure performance)
Si vous ne vous souciez pas des performances et préférez un code plus petit, utilisez simplement:
la source
Solution finale:
la source
Tout d'abord, je copie toutes les valeurs des tableaux dans un seul tableau, puis je supprime les valeurs en double dans le tableau. Ligne 12, expliquant si le même nombre se produit plus que le temps, mettez une valeur supplémentaire de déchets en position «j». À la fin, parcourez du début à la fin et vérifiez si la même valeur de garbage se produit, puis jetez-la.
la source
ArrayList
, pour stocker le résultat de l'union.Integer
plutôt que deint
. Ensuite, vous pouvez utiliser à lanull
place de votre "valeur de garbage". Les "valeurs de garbage" ou "valeurs sentinelles" sont généralement une mauvaise idée, car ces valeurs peuvent toujours apparaître dans l'entrée.Après les tests, voici ma meilleure approche d'intersection.
Vitesse plus rapide par rapport à l'approche HashSet pure. HashSet et HashMap ci-dessous ont des performances similaires pour les tableaux de plus d'un million d'enregistrements.
En ce qui concerne l'approche Java 8 Stream, la vitesse est assez lente pour une taille de tableau supérieure à 10k.
J'espère que cela peut vous aider.
la source
conserverAll (), méthode utilisée pour rechercher un élément commun..ie; intersection list1.retainAll (list2)
la source
Si vous aviez vos données dans des ensembles, vous pourriez utiliser la
Sets
classe de Guava .la source
Si le nombre correspond à celui que je vérifie, il se produit la première fois ou non avec l'aide de "indexOf ()" si le numéro correspond à la première fois, puis imprimez et enregistrez dans une chaîne de sorte que la prochaine fois que le même numéro correspond, il est gagné ' t print car en raison de "indexOf ()", la condition sera fausse.
}
la source