Java: Comment effectuer des opérations de liste avec des définitions différentes d'égaux?
J'ai deux listes de pojos génériques. Je dois effectuer des opérations définies sur les listes en fonction de différentes manières de comparer les pojos dans les listes. P>
Par exemple, si mon pojo avait la structure suivante: P>
public class GenericPojo { private String id; private String address; private String city; private String country; private String extraDetails; }
7 Réponses :
Si vos listes ne contiennent aucun duplicate (avec repsect dans les classes de comparaison personnalisées hypothétiques), vous pouvez utiliser deux arbres à la place, instancié avec vos deux comparateurs respectivement. P>
Un inconvénient (en dehors de la contrainte de duplication) est que l'ordre que vous obtenez lors de l'itération des éléments dépend des comparateurs. P>
Compte tenu de vos exigences spécifiques sur l'égalité, Liste # removeall () code>
et Liste # retention () code>
ne correspondra pas à vos besoins Il faut une implémentation personnalisée pour faire quelque chose de similaire aux deux opérations. P>
Il n'y a pas de solution qui obéit le contrat de liste, et aucune des implémentations de liste existantes ne vous permet de fournir un comparateur. Le contrat de liste définit le comportement de la liste en termes de La suggestion d'utiliser des rayons avec différents comparateurs est également une violation du contrat si la méthode En pratique, vous devrez peut-être mettre en œuvre vos propres cours de liste. Vous pouvez en faire une implémentation de la liste qui ne suive pas strictement le contrat de liste, mais vous devez faire attention à ce que cela ne casse pas d'autres méthodes / classes de la bibliothèque. P> (objet) de chaque élément code> méthode. P>
de comparateur code> est incompatible avec chaque élément
Equals (objet) code>. p>
Si vous ne voulez pas programmer les opérations définies vous-même et em> Ça ne vous dérange pas de gaspiller de la CPU et des ressources de mémoire, vous pouvez: P>
laid mais simple. p>
wripspojo code> s basé sur votre
genericpojo code> s li>
WreavedPojo Code> Des implémentations appropriées de
Equals () Code> LI>
wreaviPojo code> pour effectuer l'opération sur li>
GenericPojo CODE> S revenir à leurs conteneurs d'origine (si nécessaire) après la fin de la fin de l'opération. LI>
ul>
Vous pouvez utiliser tout cela dans les objets de domaine par l'approche suivante: p>
égaux ( code> ... ) code> sur génériquepojo code> uniquement sur ID code>. LI>.
- Définir
wreaviPojo code> en tant que wrapper autour de genericpojo code> avec un égale ( code> ... ) code> basé sur le supplément genericpojo code> champs. li>
- Pour le deuxième cas d'utilisation, utilisez une liste d'instances enveloppées. li>
ol>
Je suggère que le problème de la racine tente d'avoir une seule classe de domaine avec des définitions différentes de l'égalité. P>
La base Pojo n'est pas celle que j'ai le contrôle, peut-être une solution de wrapper est plus appropriée pour ce que j'essaie d'accomplir
Si vous devez manipuler la classe de votre contrôle, je suggérerais d'utiliser la délégation. Voici mon essai: p>
richlist code> wrapper autour de code> s Implémentation de la liste CODE> Liste CODE> CONTRAT, basée sur le motif de décorateur . li>
- Créer un
EqualityChecker Code> Inteface, avec une méthode unique `Boolean public égal (T T1, T, T2). Li>
- implémente cette interface pour votre pojo générique deux fois: une vérification de l'identifiant et de l'autre vérifiant les autres champs. LI>
- Ajoutez les deux méthodes qui vous intéressent (ensemble de soustraction et définissez l'intersection), mais avec un argument supplémentaire qui correspond à l'instance de béton code> code> qui fera le test d'égalité pour vous. li>
ol>
Vous pouvez donc ajouter les deux opérations à la liste code> S pour tout type d'objet pour lequel vous avez écrit un EqualityChecker code>. P>.
d'autres améliorations: strong> Vous pouvez également écrire un em> EqualityChecker code> qui appelle simplement la méthode des objets comparés. Vous pouvez ensuite surcharger les deux nouvelles opérations pour défaut le EqualityChecker code>. P>
Les deux opérations que vous essayez d'effectuer sont fonctionnelles, bien que Java ne le supporte pas très bien et que vous les écrivez d'une manière très différente. Vous devrez peut-être repenser ce que vous essayez de réaliser avec Java.
Ce que vous faites est de faire une opération sur une projection du type de données (c.-à-d. Pour un sous-ensemble de champs) P>
Les opérations que vous utilisez sont également définies, plutôt que des opérations de liste. par exemple. Vous ne pouvez pas prendre une intersection de deux listes (ou au moins que vous devez définir ce que cela signifie) peut ne pas effectuer exactement comme vous vous attendez également à la liste. P>
Imaginez que vous ayez une méthode qui retourne une collection de pojos avec juste les champs que vous spécifiez. J'ai écrit une bibliothèque pour le faire efficacement avec une classe générée dynamiquement dans le passé, consultez Java fonctionnel ou similaire. P>
Set<PojoWithThreeFields> intersection = project(list1, "id", "address", "city", "country"); intersection.retainAll(project(list2, "id", "address", "city", "country"));
C'est ma première question, si j'ai fait des erreurs de style ou d'autres erreurs, veuillez éditer et me faire savoir ce que j'ai mal fait.
Remarque Vous pouvez obtenir un texte formaté comme code en l'en train de l'indenter au moins quatre espaces. Vous pouvez également utiliser le bouton de code ("101 \ n010") dans la barre de rédaction en retrait.
Lors de l'intersection, voulez-vous deux listes, les deux extradétails sont représentés ou l'une des deux suffisamment?
Non, on suffit. Peut-être que l'intersection est la mauvaise façon de le mettre. Je suppose que quelque chose de similaire à list1.Retainall (List2) impliquant un comparateur personnalisé est davantage ce que j'essaie d'atteindre.