Quel est le moyen le plus rapide pour comparer les deux jeux en Java?
Je suis en train d'essayer d'optimiser un morceau de code qui compare les éléments de la liste.
Par exemple.
public void compare(Set<Record> firstSet, Set<Record> secondSet){
for(Record firstRecord : firstSet){
for(Record secondRecord : secondSet){
//comparing logic
}
}
}
Veuillez prendre en compte que le nombre d'enregistrements dans des ensembles sera élevé.
Grâce
Shekhar
- Il n'est pas possible d'optimiser les boucles sans le savoir (et de modifier) la comparaison de la logique. Pourriez-vous montrer plus de votre code?
Vous devez vous connecter pour publier un commentaire.
Cela dépend vraiment de ce que vous voulez faire dans la logique de comparaison... c'est à dire ce qui se passe si vous trouvez un élément dans un ensemble pas dans l'autre? Votre méthode a un
void
type de retour donc je suppose que vous allez faire le travail nécessaire à cette méthode.Contrôle plus fin si vous en avez besoin:
Si vous avez besoin d'obtenir les éléments qui sont dans un jeu et pas l'autre.
EDIT:
set.removeAll(otherSet)
renvoie un booléen, pas un jeu. Pour utiliser removeAll(), vous devrez copier l'ensemble, puis l'utiliser.Si le contenu de
one
ettwo
sont tous les deux vides, alors vous savez que les deux ensembles sont égaux. Si non, alors vous avez les éléments qui ont fait le jeux de l'inégalité.Vous avez mentionné que le nombre de dossiers pourrait être élevé. Si le sous-jacent de la mise en œuvre est un
HashSet
puis l'extraction de chaque enregistrement est fait dansO(1)
temps, de sorte que vous ne pouvez pas vraiment obtenir beaucoup mieux que cela.TreeSet
estO(log n)
.equals
est plus rapide que les deux appels àcontainsAll
dans le pire des cas; voir ma réponse.Si vous voulez simplement savoir si les jeux sont l'égalité, la
equals
méthode surAbstractSet
est mis en œuvre à peu près comme ci-dessous:Remarque comment il optimise la commune les cas où:
Après,
containsAll(...)
sera de retourfalse
dès qu'il trouve un élément dans l'autre jeu qui n'est pas dans cet ensemble. Mais si tous les éléments sont présents dans les deux ensembles, il aura besoin de tous les tester.Le pire des cas de la performance, par conséquent, se produit lorsque les deux ensembles sont égaux, mais pas les mêmes objets. Ce coût est généralement
O(N)
ouO(NlogN)
en fonction de la mise en œuvre dethis.containsAll(c)
.Et vous vous en approchez-à-pire des cas, la performance si les jeux sont grands et ne diffèrent que dans un petit pourcentage des éléments.
Mise à JOUR
Si vous êtes prêt à investir du temps dans un ensemble personnalisé de mise en œuvre, il y a une approche qui peut améliorer la "presque le même cas".
L'idée est que vous avez besoin pour pré-calculer et de mettre en cache une table de hachage pour l'ensemble de sorte que vous pouvez obtenir le jeu actuel de hashcode de la valeur dans
O(1)
. Ensuite, vous pouvez comparer le hashcode pour les deux ensembles comme une accélération.Comment pourriez-vous mettre en œuvre un hashcode comme ça? Ainsi, si l'ensemble hashcode était:
ensuite, vous pouvez à moindre coût mise à jour de l'ensemble de la mise en cache hashcode chaque fois que vous avez ajouté ou supprimé un élément. Dans les deux cas, il vous suffit de XOR de l'élément hashcode avec le jeu actuel hashcode.
Bien sûr, cela suppose que l'élément hashcodes sont stables tandis que les éléments sont membres d'ensembles. Il suppose également que les classes d'éléments hashcode fonction donne une bonne répartition. C'est parce que quand les deux hashcodes sont les mêmes, vous avez encore de revenir à la
O(N)
comparaison de tous les éléments.Vous pourriez prendre cette idée un peu plus loin ... du moins en théorie.
AVERTISSEMENT - Ce n'est que spéculation. Une "expérience de pensée" si vous le souhaitez.
Supposons que votre élément de la classe possède une méthode de retour d'un crypto sommes de contrôle pour l'élément. Mettre en œuvre l'ensemble de la somme de contrôle par XORing sommes retournés pour les éléments.
Qu'est-ce nous acheter?
Bien, si nous supposons que rien sournoise qui se passe, la probabilité que deux inégalité de définir les éléments ont le même N bits de sommes est de 2N. Et la probabilité 2 inégale ensembles ont le même N bits de sommes de contrôle est également 2N. Donc, mon idée est que vous pouvez mettre en œuvre
equals
comme:Sous les hypothèses ci-dessus, cela ne fera que vous donner la mauvaise réponse une fois dans 2N de temps. Si vous faites N assez grand (par exemple 512 bits), la probabilité d'une mauvaise réponse devient négligeable (par exemple, environ 10-150).
L'inconvénient est que le calcul de la crypto sommes de contrôle pour les éléments est très cher, surtout que le nombre de bits augmente. Si vous avez vraiment besoin d'un mécanisme efficace pour memoizing les sommes de contrôle. Et qui pourrait être problématique.
Et l'autre inconvénient, c'est qu'une probabilité non nulle d'erreur peut être inacceptable, peu importe comment petit la probabilité est. (Mais si c'est le cas ... comment voulez-vous traiter le cas où un rayon cosmique retourne une critique peu? Ou si c'simultanément retourne les mêmes bits dans les deux cas d'un système redondant?)
Il y a une méthode dans la Goyave
Sets
qui peut aider ici:Vous avez la solution suivante de https://www.mkyong.com/java/java-how-to-compare-two-sets/
Ou si vous préférez utiliser une seule instruction return:
Il y a un O(N) solution pour des cas très spécifiques où:
Le code suivant suppose que les deux ensembles sont basés sur les registres comparables. Une méthode similaire pourrait être basé sur un Comparateur.
Si vous utilisez
Guava
bibliothèque, il est possible de faire:Et ensuite faire une conclusion sur la base de ces.
Je mettrais le secondSet dans une table de hachage avant la comparaison. De cette façon, vous réduirez le deuxième de la liste de temps de recherche à n(1). Comme ceci:
Je pense que la méthode de référence avec la méthode equals peut être utilisé. Nous supposons que le type d'objet sans l'ombre d'un doute a sa propre méthode de comparaison. La plaine et simple exemple est ici,
set.equals(set2)