7
votes

Java: Comment effectuer des opérations de liste avec des définitions différentes d'égaux?

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;
}


4 commentaires

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.


7 Réponses :


1
votes

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.

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.


0 commentaires

1
votes

Compte tenu de vos exigences spécifiques sur l'égalité, Liste # removeall () et Liste # retention () ne correspondra pas à vos besoins Il faut une implémentation personnalisée pour faire quelque chose de similaire aux deux opérations.


0 commentaires

0
votes

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 (objet) de chaque élément méthode.

La suggestion d'utiliser des rayons avec différents comparateurs est également une violation du contrat si la méthode de comparateur est incompatible avec chaque élément Equals (objet) .

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.


0 commentaires

0
votes

Si vous ne voulez pas programmer les opérations définies vous-même et Ça ne vous dérange pas de gaspiller de la CPU et des ressources de mémoire, vous pouvez:

  • Construct wripspojo s basé sur votre genericpojo s
  • Donnez au WreavedPojo Des implémentations appropriées de Equals ()
  • Créer de nouvelles listes du type approprié de wreaviPojo pour effectuer l'opération sur
  • Copiez le GenericPojo S revenir à leurs conteneurs d'origine (si nécessaire) après la fin de la fin de l'opération.

    laid mais simple.


0 commentaires

0
votes

Vous pouvez utiliser tout cela dans les objets de domaine par l'approche suivante:

  1. implémenter égaux ( ... ) sur génériquepojo uniquement sur ID . .
  2. Définir wreaviPojo en tant que wrapper autour de genericpojo avec un égale ( ... ) basé sur le supplément genericpojo champs.
  3. Pour le deuxième cas d'utilisation, utilisez une liste d'instances enveloppées.

    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é.


1 commentaires

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



2
votes

Si vous devez manipuler la classe de votre contrôle, je suggérerais d'utiliser la délégation. Voici mon essai:

  1. Créez un richlist wrapper autour de s Implémentation de la liste Liste CONTRAT, basée sur le motif de décorateur .
  2. Créer un EqualityChecker Inteface, avec une méthode unique `Boolean public égal (T T1, T, T2).
  3. 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.
  4. 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 qui fera le test d'égalité pour vous.

    Vous pouvez donc ajouter les deux opérations à la liste S pour tout type d'objet pour lequel vous avez écrit un EqualityChecker . .

    d'autres améliorations: Vous pouvez également écrire un EqualityChecker qui appelle simplement la méthode des objets comparés. Vous pouvez ensuite surcharger les deux nouvelles opérations pour défaut le EqualityChecker .


0 commentaires

0
votes

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"));


0 commentaires