2010-11-03 19 views
7

J'ai deux collections dans une classe Java. La première collection contient les données précédentes, la seconde contient les données mises à jour de la collection précédente.Comparaison de deux collections en Java

Je voudrais comparer les deux collections, mais je ne suis pas sûr de la meilleure façon de l'implémenter efficacement. Les deux collections contiendront la même quantité d'éléments. Basé alors sur le carType étant le même dans chaque collection je veux exécuter la méthode carType.

Toute aide est appréciée

+4

http: // stackoverflow .com/questions/23445/comment-mieux-comparer-deux-collections-en-java-et-agir-sur-eux –

+0

Quel résultat attendez-vous de la comparaison; vous voulez extraire les éléments qui n'ont pas changé? Avez-vous besoin de connaître leur index dans les collections (c'est pareil dans les deux) ... – pgras

+0

Toutes mes excuses pour la vague description pgras. Les collections seront dans le même ordre et la même taille. Certaines des données de la nouvelle collection seront mises à jour depuis la collection précédente. Basé sur carType, registrationNo et insurancePolicy étant les mêmes dans les deux collections, je vais exécuter un autre code. – damien535

Répondre

21

Difficile d'aider, car vous ne nous avez pas dit comment vous aimez comparer les collections (taille égale). Quelques idées, dans l'espoir on s'adapter:

Comparer les collections si elles contiennent les mêmes objets dans le même ordre

Iterator targetIt = target.iterator(); 
for (Object obj:source) 
    if (!obj.equals(targetIt.next())) 
    // compare result -> false 

Comparer les collections si elles contiennent les mêmes objets dans l'ordre quelconque

for (Object obj:source) 
    if (target.contains(obj)) 
    // compare result -> false 

Trouver des éléments dans d'autres collection qui a changé

Iterator targetIt = target.iterator(); 
for (Object obj:source) 
    if (!obj.equals(targetIt.next()) 
    // Element has changed 

Sur la base de votre commentaire, cet algorithme ferait. Il recueille toutes les voitures qui ont été mises à jour. Si le résultat de la méthode est une liste vide, les deux collections contiennent des entrées égales dans le même ordre. L'algorithme repose sur sur une implémentation correcte de equals() sur le type Car!

public List<Car> findUpdatedCars(Collection<Car> oldCars, Collection<Car> newCars) 
    List<Car> updatedCars = new ArrayList<Car>(); 
    Iterator oldIt = oldCars.iterator(); 
    for (Car newCar:newCars) { 
    if (!newCar.equals(oldIt.next()) { 
     updatedCars.add(newCar); 
    } 
    } 
    return updatedCars; 
} 
+0

Vous utilisez 'new' dans votre paramètre, ce qui n'est pas autorisé. Aussi, où est ce 'new' utilisé dans' findUpdatedCars'? –

+0

@Shervin - merci pour la remarque! Correction des problèmes –

+0

si cela ne vous dérange pas j'ai changé la valeur de retour –

6
  • itérer sur la première collection et l'ajouter dans un Map<Entity, Integer>Entity la classe est stockée dans votre collection et le Integer représente le nombre de fois où il se produit.
  • Effectuez une itération sur la deuxième collection et, pour chaque élément, tentez de la rechercher dans Map - Si elle existe, décrémentez la valeur Integer d'une unité et effectuez toute action nécessaire lorsqu'une correspondance est trouvée. Si la valeur Integer a atteint zéro, supprimez l'entrée (Entité, Entier) de la carte.

Cet algorithme s'exécutera en temps linéaire en supposant que vous avez implémenté une méthode efficace hashCode().

1

Si pas inquiet des cas comme (2,2,3), (2,3,3):

static <T> boolean equals(Collection<T> lhs, Collection<T> rhs) { 
    return lhs.size() == rhs.size() && lhs.containsAll(rhs) && rhs.containsAll(lhs); 
} 
8

Des Arithmétique ensemble, les ensembles A et B sont égaux ssi A sous-licence B et B subsetequal A.Ainsi, en Java, étant donné deux collections A et B vous pouvez vérifier leur égalité sans tenir compte de l'ordre des éléments avec

boolean collectionsAreEqual = A.containsAll(B) && B.containsAll(A); 
+1

cette déclaration est vraie pour les ensembles mais peut ne pas être vraie pour les listes ou autres structures qui permettent dupliquer les entrées (en d'autres termes, utiliser des ensembles si possible pour simplifier votre logique) – cfeduke

3

légèrement mis à jour un compte tenu des valeurs nulles:

static <T> boolean equals(Collection<T> lhs, Collection<T> rhs) { 
    boolean equals = false; 
    if(lhs!=null && rhs!=null) { 
     equals = lhs.size() == rhs.size() && lhs.containsAll(rhs) && rhs.containsAll(lhs); 
    } else if (lhs==null && rhs==null) { 
     equals = true; 
    } 
return equals; 
}