7
votes

Collection Java pour ce cas d'utilisation

Disons que nous avons un tas d'objets de voiture.

Chaque voiture a des propriétés distinctives par ex. fabricant, modèle, année, etc. (Ceux-ci peuvent être utilisés pour créer des hashcodes distincts).

Chaque voiture a une liste d'objets de PASCHEROFFER (un objet AchatOffer contient des prix \ détaillante).

Nous recevons des listes de voitures de plusieurs sources différentes, chaque voiture avec un seul bonheur. La chose est que ces listes peuvent se chevaucher - une voiture peut apparaître dans plus d'une liste.

Nous souhaitons regrouper les listes dans une seule collection de voitures où chaque voiture détient toutes les offres d'achat rencontrées pour cela.

Mon problème est de choisir quoi de collecte pour utiliser dans ce processus d'agrégation:

se sent naturel d'utiliser Java.Util.Hashashset pour tenir nos voitures, de cette façon lorsque vous passez sur les différentes listes de voitures, nous pouvons vérifier si une voiture existe déjà dans l'ensemble de l'amortissement O (1), Toutefois, vous ne pouvez pas récupérer un élément d'un ensemble (dans notre cas - lorsque nous allons rencontrer une voiture qui existe déjà dans l'ensemble - nous aurions aimé récupérer cette voiture à partir de l'ensemble sur la base de son hashcode d'identification et d'ajouter des offres d'achat) .

Je peux utiliser un haschmap dans lequel le hashcode de chaque voiture correspond à l'objet de la voiture réel, mais ce n'est probablement pas la solution de livres scolaires puisqu'il est dangereux - je devrais m'assurer que chaque hashcode plante sur une voiture avec une voiture avec Ce hashcode - il pourrait y avoir une incohérence. Bien sûr, peut faire une structure de données désignée qui garantit cette cohérence - ne devrait-on pas exister déjà?

Quelqu'un peut-il suggérer la structure de données que je suis après, ou signalez-vous une erreur de conception? Merci.


3 commentaires

Pourriez-vous clarifier ce que vous entendez par danger?


Si nous décidons que nous utilisons une carte qui mappe un hashcode sur un objet de voiture avec ce hashcode, rien ne nous empêche d'insérer dans cette carte une valeur de clé incorrecte, par exemple une clé arbitraire X qui mappe à une voiture avec un casque différent de celui-ci. X. Si cette structure de données devait être utilisée par d'autres programmeurs, c'est-à-dire des utilisateurs clients du code, ce qui serait inacceptable.


Cochez cette case Répondre pour un problème similaire.


9 Réponses :


6
votes

Comme il s'agit d'une relation de plusieurs à plusieurs, vous avez besoin d'une multimalisation bidirectionnelle. La voiture est la clé du premier, avec une liste d'utilisateurs comme valeur. Le bilanoraire est la clé du second, avec une liste de voitures comme valeur.

La mise en œuvre sous-jacente est deux hachemaps.

Mettez une API sur le dessus pour obtenir le comportement dont vous avez besoin. Ou voir si collections Google peut vous aider. C'est une combinaison d'un bimap et de deux multimples.


2 commentaires

Je comprends pourquoi une multimum-carte serait utile, mais pourquoi la bidirectionnalité? Mon problème avec une multimôle est que la liste est une propriété de l'objet de voiture, c'est-à-dire que ce n'est pas quelque chose qui est externe à l'objet de la voiture, mais est contenu dans celui-ci.


Peut-être qu'il devrait être externalisé. En ce qui concerne un membre de données de la voiture ou une classe distincte n'est que deux choix de conception parmi beaucoup. Vous connaissez peut-être votre problème mieux que moi. Ou peut être pas. Vous avez dit plus tôt qu'une voiture avait un acheteur, et dans votre commentaire, c'est une liste de candidats. Lequel est-ce?



3
votes

Le datrastructure de base doit être un HashMap > . Cela permet de stocker et de recevoir toutes les offres pour une voiture sélectionnée.

Maintenant, vous devrez peut-être trouver une implémentation appropriée pour car.equals () pour assurer, que "voitures" provenant de différentes sources sont vraiment identiques. Qu'en est-il de baser égale () sur un identifiant unique pour une voiture de monde réelle (VIN)?


1 commentaires

Welp, Ouais, Hashmap > serait parfait si ce n'était pas pour le fait que chaque voiture contient une liste en tant que propriété. Peut dire qu'un objet de voiture est composé de deux parties: une pièce d'identification (disons que chaque voiture a en effet un VIN unique) et la liste des offres d'achat.



0
votes

Créer tout la classe personnalisée qui étend son hachage Définir la méthode de remplacement de



Vérifiez le code de hachage d'OS est identique ou non et renvoie le résultat de retour en fonction, et ajoutez un objet à l'ensemble de et uniquement s'il ne contenant pas cet objet


0 commentaires

0
votes

Que diriez-vous d'une nouvelle classe d'agrégation personnalisée? Définissez le crockode de telle sorte que l'ID de la voiture agit comme une clé et remplacez les égaux () en conséquence. Définissez une méthode personnalisée pour accepter votre voiture d'origine et faire une opération syndicale sur les listes. Enfin stocker les objets personnalisés d'un hashset pour obtenir une recherche de temps constante.

en termes puristes, l'agrégation est un comportement au-delà de la portée d'un seul objet. Le modèle de visiteur tente de résoudre un problème similaire.

Alternativement si vous avez un magasin de données SQL, un simple sélection d'utilisation de groupe par le truc.


0 commentaires

5
votes

Je pense que vous avez vraiment besoin (au moins) A (au moins) un hashmap > code> ... comme suggéré par @andreas_d

Votre objection que chaque voiture code> a déjà une liste code> est à côté du point. La liste dans le hashmap code> est la liste d'agrégats, contenant tous em> des objets de tous les objets voiture code> des objets qui représentent le Même voiture physique. p>

Le point de créer une nouvelle liste est d'éviter de modifier les listes d'origine sur les objets d'origine voiture code>. (Si ce n'était pas une préoccupation, vous pourriez choisir une instance de voiture code> à partir de l'ensemble qui représente une voiture physique et fusionner le aimefer code> objets des autres dans cette liste .) p>

Je ne suis pas tout à fait sûr que @duffymo a suggéré une carte bidirectionnelle entre, mais je pense que c'est parce que les objets code> voiture code> de différentes sources peuvent avoir complémentaires ( ou contradictoire) Informations pour la même voiture physique. En gardant toutes les instances, vous évitez de jeter les informations. (Encore une fois, si vous êtes heureux de supprimer les informations de la mutate et / ou de rejeter, vous pouvez tenter de fusionner les informations sur chaque voiture dans une seule voiture code> objet code>. P>


Si vous vous êtes vraiment préoccupé par la préservation des informations et que vous avez été prêt à fusionner des trucs willy-nilly, l'approche suivante fonctionnerait probablement: p>

  HashMap<Car, Car> map = new HashMap<Car, Car>(...);
  for (Car car : carsToBeAggregated) {
      Car master = nap.get(car);
      if (master == null) {
          map.put(car, car);
      } else {
          master.offers.addAll(car.offers);
          // optionally, merge other Car information from car to master
      }
  }


2 commentaires

+1 pour la deuxième partie de la réponse. Une voiture -> Carte de la voiture est la structure de données minimale qui fournit tout ce que l'OP a demandé. (Bien que peut-être qu'ils voulaient des choses qu'ils ne demandaient pas.)


Il n'y a pas d'autre information, ce n'est tout simplement pas un scénario nombreux à plusieurs. Une bonne réponse, la deuxième partie de votre réponse est une très belle solution!



-1
votes

Pourquoi ne pas utiliser une base de données d'objet pour cela? Vous pouvez stocker n'importe quel graphique d'objet que vous vouliez, et vous obtiendrez une API de recherche avec laquelle vous pourriez faire n'importe quel mécanisme de relation / récupération que vous vouliez. Une simple collection pourrait fonctionner, mais on dirait que vous voulez une relation plus complexe qu'une collection fournirait. Regardez dans db4o (http://db4o.com) - C'est très puissant pour ce genre de chose.


4 commentaires

Java vous permet de définir un graphique d'objet que vous voulez aussi. Ajout d'une base de données au mélange - sans avoir besoin de fonctionnalités telles que l'atomicité des transactions et la sérialisation - est un moyen parfaitement délicieux de rendre le problème beaucoup plus difficile.


En toute justice, l'ajout d'une base de données comme DB4O - une base de données d'objets - ne rend pas une exigence d'acide afin d'interagir avec la base de données. Et DB4O vous permet de rechercher ce graphique d'objet facilement et facilement. Ce n'est pas une exigence, bien sûr - la sérialisation Java fonctionne. Mais encore une fois: ça ne sonne pas comme un graphique simple est ce qu'il cherche.


L'OP n'a pas besoin de sérialisation. Il a juste besoin d'une carte de hachage. Il est intégré et trivial à utiliser. DB4O n'est pas intégré et n'est pas aussi trivial à utiliser. C'est une excellente solution pour certains problèmes , mais pas celui-ci! (Sauf si l'OP n'en a besoin beaucoup plus que ce qu'ils demandent.)


Bien sûr, c'est assez juste. Pourtant, j'ai pensé que si une simple collection d'objets était tout ce dont il avait besoin, ce serait assez évident pour lui, alors il avait probablement besoin de plus. Et je dirais que db4o est assez trivial à utiliser - ESP pour les graphiques en mémoire et l'ajout de dépendances à l'application Java est un comportement assez normal. (Bien que je note que je fais beaucoup de choses EE, alors peut-être que c'est plus normal dans cette arène que d'autres.)



1
votes

Je préférerais utiliser un hashmap > , comme suggéré avant (Andreas, Stephen), principalement si l'objet de la voiture est non la liste des offres d'achat.
Sinon, je envisagerais d'utiliser un hashmap ou, meilleur imo, un hashmap s'il y a une pièce d'identité unique pour chaque voiture.

Il peut NON MAPITER SIZE SIZE LE HASHCODE DE LA VOITURE À LA VOITURE, comme indiqué dans la question, car les voitures distinctes peuvent avoir le même hashcode!

(Quoi qu'il en soit, je créerais une classe propre à stocker et à gérer les voitures. Cela contiendrait le haschmap, ou celui-ci, il est donc facile de modifier la mise en œuvre sans avoir à modifier son interface)


2 commentaires

Je me demandais si une structure de données telle que celle que vous avez mentionnée dans le dernier paragraphe de votre réponse existe déjà. Devinez ça ne le fait pas.


@bloodcell - Je ne sais aucun, malgré je pense que le hashset est mis en œuvre (plus ou moins) de cette façon; Mais il manque une méthode de récupération de l'instance effectivement enregistrée.



0
votes
    //alt. 2
    List<Offer> offers;
    List<Car> cars;
    Map<Integer, List<Offer>> mapCarIdToOffers;
    Map<Integer, List<Car>> mapOfferIdToCars;
    public void List<Offer> getOffersForCarId(int aCarId);
    public void List<Car> getCarsForOfferId(int anOfferId);

0 commentaires

0
votes

welp, ouais, hashmap > serait parfait si ce n'était pas pour le fait que Chaque voiture contient une liste comme une propriété. Peut dire qu'un objet voiture est composé de deux parties: une partie d'identification (disons que chaque voiture a en effet un VIN unique) et la liste de PASSAMEROFFER S.

Dans ce cas, divisez la classe de voiture en deux classes - la classe de cartype avec les attributs d'identification, puis la partie de liste (peut-être que les deux utilisées les deux utilisées par voiture ). Ensuite, utilisez mappe pour votre DaSTRUCTURE (ou MULTIMAP ).


0 commentaires