J'ai deux listes avec différents objets en eux.
List<Object1> list1;
List<Object2> list2;
Je veux vérifier si un élément de list1 existe dans list2, basé sur un attribut spécifique (Object1 et Object2 ont (entre autres), un attribut mutuel (de type Long), nommé attributeSame).
maintenant, je le fais comme ça:
boolean found = false;
for(Object1 object1 : list1){
for(Object2 object2: list2){
if(object1.getAttributeSame() == object2.getAttributeSame()){
found = true;
//also do something
}
}
if(!found){
//do something
}
found = false;
}
Mais je pense qu’il existe un moyen plus rapide et meilleur de le faire :) Quelqu'un peut-il le proposer?
Merci!
Si vous avez juste besoin de tester l’égalité de base, vous pouvez le faire avec le JDK de base sans modifier les listes d’entrée sur une ligne.
!Collections.disjoint(list1, list2);
Si vous avez besoin de tester une propriété spécifique, c'est plus difficile. Je recommanderais, par défaut,
list1.stream()
.map(Object1::getProperty)
.anyMatch(
list2.stream()
.map(Object2::getProperty)
.collect(toSet())
::contains)
... qui rassemble les valeurs distinctes dans list2
et teste chaque valeur dans list1
pour la présence.
Vous pouvez utiliser Apache Commons CollectionUtils :
if(CollectionUtils.containsAny(list1,list2)) {
// do whatever you want
} else {
// do other thing
}
Cela suppose que vous avez correctement surchargé la fonctionnalité égal à vos objets personnalisés.
Il y a une méthode de Collection
nommée retainAll
mais ayant certains effets secondaires pour vous référence
Conserve uniquement les éléments de cette liste contenus dans la collection spécifiée (opération facultative). En d'autres termes, supprime de cette liste tous les éléments qui ne sont pas contenus dans la collection spécifiée.
true si cette liste a changé à la suite de l'appel
C'est comme
boolean b = list1.retainAll(list2);
Louis répond est correct, je veux juste ajouter un exemple:
listOne.add("A");
listOne.add("B");
listOne.add("C");
listTwo.add("D");
listTwo.add("E");
listTwo.add("F");
boolean noElementsInCommon = Collections.disjoint(listOne, listTwo); // true
Pour raccourcir la logique de Narendra, vous pouvez utiliser ceci:
boolean var = lis1.stream().anyMatch(element -> list2.contains(element));
manière plus rapide nécessitera un espace supplémentaire.
Par exemple:
mettre tous les éléments d'une liste dans un hachage (vous devez implémenter vous-même la fonction de hachage pour utiliser object.getAttributeSame ())
Parcourez l'autre liste et vérifiez si un élément est présent dans le HashSet.
De cette façon, chaque objet est visité au plus une fois. et HashSet est assez rapide pour vérifier ou insérer un objet dans O (1).
pour le rendre plus rapide, vous pouvez ajouter une pause; de cette façon, la boucle s’arrêtera si elle est trouvée à true:
boolean found = false;
for(Object1 object1 : list1){
for(Object2 object2: list2){
if(object1.getAttributeSame() == object2.getAttributeSame()){
found = true;
//also do something
break;
}
}
if(!found){
//do something
}
found = false;
}
Si vous aviez des cartes au lieu de listes avec comme clés l'attributSame, vous pourriez vérifier plus rapidement si une valeur d'une carte correspond à une valeur correspondante ou non.
Selon le JavaDoc pour le .contains(Object obj)
:
Renvoie true si cette liste contient l'élément spécifié. Plus formellement, renvoie vrai si et seulement si cette liste contient au moins un élément e tel que (o == null? E == null: o.equals (e)).
Donc, si vous substituez votre méthode .equals()
à votre objet donné, vous devriez pouvoir faire: if(list1.contains(object2))...
Si les éléments sont uniques (c.-à-d. Qu'ils ont des attributs différents), vous pouvez remplacer les .equals()
et .hashcode()
et tout stocker dans HashSets
. Cela vous permettra de vérifier si l'un contient un autre élément en temps constant.
org.springframework.util.CollectionUtils
boolean containsAny(Java.util.Collection<?> source, Java.util.Collection<?> candidates)
Return true if any element in 'candidates' is contained in 'source'; otherwise returns false
Avec Java 8
, on peut faire comme ci-dessous pour vérifier si une liste contient un élément d’un autre
boolean var = lis1.stream().filter(element -> list2.contains(element)).findFirst().isPresent();
Pouvez-vous définir le type de données que vous détenez? est-ce le big data? est-ce trié? Je pense que vous devez envisager différentes approches d'efficacité en fonction des données.
Par exemple, si vos données sont volumineuses et non triées, vous pouvez essayer de parcourir les deux listes ensemble par index et de stocker chaque attribut de liste dans un autre assistant de liste. vous pouvez ensuite vérifier par les attributs actuels dans les listes d’aides.
bonne chance
édité: et je ne recommanderais pas de surcharger égaux. son dangereux et probablement contre votre objet oop sens.