Pourquoi le java.util.Set<V> interface fournissent pas un get(Object o) méthode?
Je comprends qu'une seule instance d'un objet en fonction de .equals() est autorisée dans un Jeu et que vous ne devriez pas "besoin" d'obtenir un objet à partir de l'Ensemble si vous avez déjà un objet équivalent, mais j'aimerais en avoir un .méthode get() qui retourne l'instance réelle de l'objet dans l'Ensemble (ou null) étant donné un équivalent de l'objet en tant que paramètre.
Toutes les idées/théories quant à pourquoi il a été conçu comme cela?
J'ai l'habitude de pirater contourner ce problème en utilisant une Carte et de faire la clé et la valeur même, ou quelque chose comme ça.
EDIT: je ne pense pas que les gens comprennent ma question jusqu'à présent. Je veux exactement instance de l'objet qui est déjà dans le jeu, pas, éventuellement, un autre objet de l'instance où .equals() renvoie la valeur true.
Pourquoi je veux que ce comportement, généralement .equals() ne prend pas en compte toutes les propriétés de l'objet. Je vais vous fournir mannequin de recherche d'objet et de revenir le réel de l'instance de l'objet dans le Jeu.
- J'ai vraiment envie de le faire, mais avec une clé d'une Carte. Comme, je veux de la Carte.getKey(K k) à retourner k' où k.est égal à(k'). Puis-je le faire avec votre hack? Ou devrai-je faire une Paire<K, V>, et le changement de ma Carte<K, V> à la Carte<K, Pair<K, V>>?
- "Contrairement à la plupart des autres types de collection, plutôt que de récupérer un élément spécifique à partir d'un ensemble, l'une généralement des tests de valeur de l'adhésion à un ensemble." en.wikipedia.org/wiki/Set_(abstract_data_type)
Vous devez vous connecter pour publier un commentaire.
Tandis que la pureté de l'argument de la méthode
get(Object)
suspect, l'intention sous-jacente n'est pas discutable.Il existe différentes classe et d'interface familles que légèrement redéfinir
equals(Object)
. Il suffit de regarder pas plus loin que les collections des interfaces. Par exemple, une ArrayList et LinkedList peut être égal; leurs contenus respectifs ont simplement besoin d'être les mêmes et dans le même ordre.Par conséquent, il y a de très bonnes raisons pour trouver le correspondant élément dans un ensemble. Peut-être une meilleure façon d'indiquer l'intention est d'avoir une méthode comme
Noter que cette API a une valeur plus large que dans un délai Défini.
À la question elle-même, je n'ai pas de théorie pour expliquer pourquoi une telle opération a été omis. Je dirai que le minimal spanning ensemble argument ne tient pas, car de nombreuses opérations définies dans les collections de l'Api sont motivés par des raisons de commodité et d'efficacité.
WeakHashMap
ne serait pas approprié parce qu'il détient de solides références à des valeurs.NSSet
classe contient à la fois un-containsObject:
méthode pour tester si un objet est contenu et renvoie un booléen, et un-member:
méthode pour obtenir l'objet qui est égal à l'objet donné. Bibliothèque standard d'OCaml Set contient à la fois unmem
méthode de test de l'effectif et d'unefind
méthode pour obtenir l'égalité de l'élément.Le problème est: Set n'est pas pour "recevoir" des objets, est pour l'ajout et de test pour la présence.
Je comprends ce que vous cherchez, j'ai eu une situation similaire, et s'est terminée à l'aide d'une carte du même objet dans une clé et une valeur.
EDIT: Juste pour clarifier: http://en.wikipedia.org/wiki/Set_(abstract_data_type)
J'ai eu la même question en java forum il y a des années. Ils m'ont dit que l'Ensemble de l'interface est définie. Il ne peut pas être modifié, car il va casser les implémentations actuelles de l'interface. Ensuite, ils ont commencé à dire des conneries, comme vous le voyez ici: "Set n'a pas besoin de la méthode get" et a commencé à forer moi que la Carte doit toujours être utilisé pour obtenir les éléments d'un ensemble.
Si vous utilisez l'ensemble uniquement pour des opérations mathématiques, comme l'intersection ou l'union, alors peut-être contient() est suffisant. Toutefois, le Jeu est défini dans les collections pour stocker des données. Je l'ai expliqué pour le besoin de get() dans le Jeu en utilisant le modèle de données relationnel.
Dans ce qui suit, une table SQL est comme une classe. Les colonnes de définir les attributs (connu sous le nom des champs en Java) et les enregistrements représentent des instances de la classe. De sorte qu'un objet est un vecteur de champs. Certains champs sont des clés primaires. Ils définissent l'unicité de l'objet. C'est ce que vous faites pour contains() en Java:
Je ne suis pas au courant de la DB à l'intérieur. Mais, vous, indiquez la clé des champs qu'une seule fois, lors de définir une table. Vous venez d'annoter la clé des champs avec @primaire. Vous ne spécifiez pas les touches deuxième temps, lorsque vous ajoutez un enregistrement à la table. Vous ne séparez pas les clés de données, comme vous le faites dans la cartographie. Tables SQL sont des ensembles. Ils ne sont pas les cartes. Pourtant, ils fournissent get() en plus de maintenir l'unicité et contient() vérifier.
Dans "l'Art de la Programmation Informatique", l'introduction de la recherche, D. Knuth dit la même chose:
Vous voyez, les données sont stocker de l'identification. Pas d'identification de pointage de données, mais de données, de l'identification à. Il poursuit:
On dirait qu'il commence à parler de la cartographie. Cependant,
Qui est, la recherche localise la clé du dépôt du dossier et il ne devrait pas "la carte" la clé de données. Les deux sont situés dans le même dossier, comme les champs de l'objet java. C'est, de l'algorithme de recherche examine les principaux champs de l'enregistrement, comme il le fait dans le jeu, plutôt que d'une touche de la télécommande, comme il le fait dans la carte.
Non plus, je ne vois aucune nécessité de dupliquer les clés dans un supplément de "jeu de clés" dans sa discussion de tri.
... ["The Art of Computer Programming", Chapitre 6, Introduction]
... ["Système de base de données de Concepts", 6e Édition]
Fondamentalement, classe décrit les attributs communs à toutes ses instances. Une table dans le relationnel fait de même. "Le plus simple de cartographie que vous aurez jamais est une propriété de la cartographie d'un seul attribut à une seule colonne." C'est le cas, je suis en train de parler.
Je suis tellement détaillé sur la preuve de l'analogie (isomorphisme) entre les objets de base de données et les enregistrements, car il y a des gens stupides qui ne l'acceptent pas (pour prouver que leur Ensemble ne doit pas avoir la obtenir méthode)
Que vous voyez dans les replays comment les gens, qui ne comprennent pas cela, dire que Défini à obtenir serait redondant? C'est parce que leur abusé de la carte, qu'ils imposent à utiliser à la place de jeu, introduit de la redondance. Leur appel à mettre(obj.getKey(), obj) stocke deux clés: la clé d'origine dans le cadre de l'objet et une copie de celui-ci dans l'ensemble des clés de la carte. La duplication est la redondance. Elle implique aussi plus de ballonnement dans le code et les déchets de la mémoire consommée lors de l'Exécution. Je ne sais pas à propos de DB internes, mais les principes de bonne conception et de la normalisation de base de données de dire que ce phénomène est une mauvaise idée - il doit y avoir une seule source de vérité. La redondance des moyens que l'incohérence peut arriver: la clé correspond à un objet qui a une clé différente. L'incohérence est une manifestation de la redondance. Edgar F. Codd proposé DB normalisation juste pour se débarrasser de licenciements et leurs déduit des incohérences. Les enseignants sont explicites sur la normalisation: La normalisation ne sera jamais de générer des deux tables avec un one-to-one relation entre eux. Il n'y a pas de raison théorique pour séparer une seule entité comme ça avec certains champs dans un seul enregistrement d'une table et d'autres dans un seul enregistrement d'une autre table
Donc, nous avons 4 arguments, pourquoi utiliser une carte pour la mise en œuvre de l'obtenir dans le jeu est mauvais:
Même si vous n'êtes pas au courant de l'ensemble d'enregistrements idée et la normalisation des données, de jouer avec les collections, vous pouvez découvrir cette structure de données et algorithme de vous-même, comme nous, org.eclipse.KeyedHashSet et C++ STL concepteurs n'.
J'ai été banni du forum Sun pour souligner ces idées. Le fanatisme est le seul argument à l'encontre de la raison et de ce monde est dominé par des fanatiques. Ils ne veulent pas voir les concepts et la façon dont les choses peuvent être différentes, améliorées. Ils ne voient que le monde réel et ne peut pas imaginer que la conception de Java Collections peuvent avoir des carences et pourrait être améliorée. Il est dangereux de rappeler la justification de choses à de telles personnes. Ils vous enseignent leur aveuglement et de sanctionner si vous ne respectez pas.
Ajouté Décembre 2013: SICP dit aussi que DB est un jeu avec un détrompeur dossiers plutôt que d'une carte:
Bien, si vous avez déjà "eu" la chose à partir du jeu, vous n'avez pas besoin de get (), ne vous? 😉
Votre approche de l'utilisation d'une Carte est La bonne Chose, je pense. Il semble que vous essayez de "accepter" des objets à l'aide de leur méthode equals (), que j'ai toujours accompli à l'aide d'une Carte comme vous le suggérez.
Je ne suis pas sûr si vous êtes à la recherche d'une explication de pourquoi Jeux de se comporter de cette façon, ou pour une solution simple au problème qu'il pose. D'autres réponses traitées avec l'ancien, voici une suggestion de ce dernier.
Vous pouvez effectuer une itération sur l'Ensemble des éléments et de tester chacun d'eux pour l'égalité à l'aide de la méthode equals (). Il est facile à mettre en œuvre et peu enclin à l'erreur. Évidemment, si vous n'êtes pas sûr si l'élément est dans le jeu ou pas, vérifier avec la méthode contains() à l'avance.
Ce n'est pas efficace par rapport à, par exemple, HashSet de la méthode contains (), qui signifie "trouver" la stockées élément, mais ne pas le retourner. Si votre jeux peut contenir de nombreux éléments, il pourrait même être une raison de l'utilisation d'un "plus lourd" solution de contournement, comme l'application de la feuille que vous avez mentionné. Cependant, si c'est important pour vous (et je ne vois l'intérêt d'avoir cette capacité), c'est probablement la peine.
Donc, je comprends que vous pourriez avoir deux objets égaux, mais ils ne sont pas de la même instance.
Comme
Dans ce cas, un.equals(b) parce qu'elles se réfèrent à la même valeur intrinsèque, mais un != b parce qu'ils sont deux objets différents.
Il existe d'autres implémentations de Jeu, tels que IdentitySet, qui faire une comparaison entre les éléments.
Cependant, je pense que vous essayez d'appliquer une philosophie différente de Java. Si vos objets sont égaux (un.equals(b)) bien que a et b ont un état différent de l'état ou de la signification, il ya quelque chose de mal ici. Vous pouvez diviser la classe en deux ou plusieurs sémantique des classes qui implémentent une interface commune - ou peut-être à reconsidérer .d'égal à égal et .hashCode.
Si vous avez Joshua Bloch de Efficace Java, avoir un regard sur les chapitres appelés "Obéir à l'économie générale du contrat lors de la substitution est égal à" et "Réduire la mutabilité".
Suffit d'utiliser la solution Map... un TreeSet et un HashSet aussi le faire, car ils sont soutenus par un TreeMap et d'une table de hachage, donc il n'y a pas de peine à le faire (actuellement il doit être un gain minime).
Vous pouvez également étendre votre Jeu préféré pour ajouter la méthode get ().
[]]
Je pense que votre seule solution, étant donné un Ensemble de mise en œuvre, est d'itérer sur ses éléments pour en trouver un qui est égal à() -- alors que vous avez l'objet réel dans l'Ensemble assorti.
Si vous pensez à ce sujet comme un ensemble mathématique, vous pouvez obtenir un moyen de trouver l'objet.
Se croisent avec une collection d'objet contenant uniquement les objets que vous voulez trouver. Si l'intersection n'est pas vide, le seul élément à gauche dans le jeu est celui que vous recherchez.
Ses pas l'utilisation la plus efficace de la mémoire, mais de son point de vue fonctionnel que mathématiquement correct.
"Je veux exactement instance de l'objet qui est déjà dans le jeu, pas, éventuellement, un autre objet de l'instance où .equals() renvoie la valeur true."
Ce n'est pas logique. Dire que vous faites:
- Vous faire maintenant:
Si vous voulez que cela n'est vrai que si un objet dans le jeu est == newFoo, de mettre en œuvre Foo equals et hashCode avec l'identité de l'objet. Ou, si vous essayez de mapper plusieurs objets égaux à canonique d'origine, puis une Carte peut être le bon choix.
s.contains(newFoo)
devrait être vrai sinewFoo.equals(originalFoo)
, comme dans la définition de.contains()
. Il veut juste alleroriginalFoo
, pasnewFoo
qu'il possède.Je pense que l'attente est égale à vraiment représenter une certaine égalité, et pas simplement que les deux objets ont la même clé primaire, par exemple. Et si equals représenté deux objets égaux, alors un obtenir serait redondante. Les cas d'utilisation que vous souhaitez suggère une Carte, et peut-être une autre valeur pour la clé, quelque chose qui représente une clé primaire, plutôt que l'ensemble de l'objet, puis correctement implémenter equals et hashcode en conséquence.
Fonctionnel Java a une mise en œuvre d'une persistante Ensemble (soutenu par un rouge/noir de l'arbre) qui, d'ailleurs, comprend un split méthode qui semble faire un peu ce que vous voulez. Elle renvoie un triplet de:
Option
qui est vide ou contient de l'objet trouvé, s'il existe, dans l'ensemble.Vous ferait quelque chose comme ceci:
est-ce que vous cherchez. Je ne sais pas pourquoi java cache.
Dire, j'ai un Utilisateur POJO avec l'ID et le nom.
ID maintient le contrat entre equals et hashcode.
le nom n'est pas partie de l'objet de l'égalité.
Je veux mettre à jour le nom de l'utilisateur basé sur l'entrée de quelque part-dire de l'INTERFACE utilisateur.
Que java jeu ne fournit pas de méthode get, j'ai besoin d'itérer sur l'ensemble de mon code et de mettre à jour le nom, quand je trouve de l'égalité de l'objet (c'est à dire lorsque l'ID correspond).
Si vous aviez méthode get, ce code pourrait être raccourcie.
Java est désormais livré avec toutes sortes de choses stupides comme javadb et amélioré pour la boucle, je ne comprends pas pourquoi dans ce cas particulier, ils sont en train d'être puriste.
J'ai eu le même problème. Je l'ai fixée par la conversion de mon jeu de la Carte, puis de les obtenir à partir de la carte. J'ai utilisé cette méthode:
Vous pouvez maintenant obtenir des éléments de votre jeu en appelant cette méthode comme ceci:
Vous pouvez remplacer les égaux dans votre classe pour laisser cocher sur seulement certaines propriétés comme Id ou nom.
si vous avez fait une demande à cet effet dans bug de Java défilé liste ici et on peut voter jusqu'à. Je pense qu'au moins la commodité de la classe java.util.Des Collections qui prend juste un jeu et un objet
et est mise en oeuvre quelque chose comme
C'est évidemment une lacune de l'Ensemble de l'API.
Simplement, je veux à la recherche d'un objet dans mon Jeu et de mise à jour de ses biens.
Et je boucle mon (Hash)de mon objet... Soupir...
Je suis d'accord que j'aimerais voir l'Ensemble des implémentations de fournir une méthode get ().
Comme une option, dans le cas où vos Objets de mettre en œuvre (ou l'application) de java.lang.Comparable, vous pouvez utiliser un TreeSet. Puis le get() type de fonction peut être obtenu en appelant au plafond() ou floor(), suivie d'une vérification de la raison d'être non-nulle et égale à la comparaison de l'Objet, telles que:
La raison pour laquelle il n'y a pas de obtenir est simple:
Si vous avez besoin pour obtenir l'objet X à partir de l'ensemble est parce que vous avez besoin de quelque chose à partir de X et que vous n'avez pas l'objet.
Si vous ne disposez pas de l'objet, puis vous avez besoin de quelques moyens (clé) pour le localiser. ..son nom, un certain nombre de ce que jamais. C'est ce que les cartes sont pour la droite.
carte.get( "clé" ) -> X!
Jeux n'ont pas les clés, vous avez besoin de yo les traverser pour obtenir les objets.
Alors, pourquoi ne pas ajouter une pratique get( X ) -> X
Qui n'a aucun sens droite, parce que vous avez X déjà, les puristes diront.
Mais maintenant, regardez comme non puriste, et de voir si vous voulez vraiment ce:
Dire que je fais l'objet Y, qui correspond à l'égal de X, de telle sorte que l'.get(Y)->X. est volia, alors je peux accéder aux données de X que je n'ai avoir des. Disons, par exemple, X est une méthode appelée obtenir drapeau() et je veux la suite de cela.
Maintenant, regardez ce code.
Y
X = map.get( Y );
Donc Y. equals( x ) vrai!
mais..
Y. drapeau() == X. drapeau() = faux. ( N'étaient-ils pas égaux ?)
Donc, vous voyez, si le jeu vous a permis d'obtenir les objets, comme Elle l'est certainement pour briser la base sémantique du signe égal. Plus tard, vous allez vivre avec peu de clones de X tous claming qu'ils sont de la même quand ils ne le sont pas.
Vous avez besoin d'une carte, pour stocker des trucs et utiliser une clé pour le récupérer.
Je comprends qu'une seule instance d'un objet en fonction de .equals() est autorisée dans un Jeu et que vous ne devriez pas "besoin" d'obtenir un objet à partir de l'Ensemble si vous avez déjà un objet équivalent, mais j'aimerais en avoir un .méthode get() qui retourne l'instance réelle de l'objet dans l'Ensemble (ou null) étant donné un équivalent de l'objet en tant que paramètre.
L'interface simple/API donne plus de liberté lors de la mise en œuvre. Par exemple, si
Set
interface serait réduit simplement à un seulcontains()
méthode, nous obtenons une définition de jeu typique pour la programmation fonctionnelle - c'est juste un prédicat, pas d'objets sont stockés. C'est également vrai pour java.util.EnumSet - elle ne contient qu'une image bitmap pour chaque valeur possible.C'est juste un avis. Je crois que nous devons comprendre que nous avons plusieurs classe java sans champs/propriétés, c'est à dire uniquement des méthodes. Dans ce cas égal à égal ne peut pas être mesurée en comparant la fonction, en est un exemple requestHandlers. Voir l'exemple ci-dessous de JAX-RS de l'application. Dans ce contexte, a fait plus de sens alors une structure de données.
Pour répondre à votre question, si vous avez un peu profonde employé de l'objet ( c'est à dire uniquement EMPID, qui est utilisé dans la méthode equals pour déterminer l'unicité ) , et si vous voulez obtenir un grand objet en faisant une recherche dans l'ensemble, n'est pas la structure des données , que son but est différent.
Liste est ordonnée à la structure de données. Donc il suit l'ordre d'insertion. Donc les données que vous mettez sera disponible à la position exacte du temps que vous avez inséré.
Rappelez-vous cette simple tableau.
Ensemble de l'onu a ordonné la structure de données. Donc, il ne suit pas un ordre. Les données que vous introduisez dans certaine position sera disponible à n'importe quelle position.
Mais il sera de retour quelque chose d'autre. Par conséquent, elle n'a pas de sens de créer une méthode obtenir dans le Jeu.
****Remarque**Pour l'explication, j'ai utilisé le type int, cette même chose est applicable pour le type d'Objet également.
Set.get(int index)
(en négligeant intervenantclear()
,remove()
,add(int index, E element)
) - la question était de savoirSet.get(Object o)
. (Downvoting principalement pour garder cette à zéro, tout au plus.)this same is applicable for Object type also
veuillez ne montrer autre chose pour les membres: en l'absence de définition/déclaration, je ne sais pas si le0
dansset.get(0)
est un indice ou d'un à - si je le faisais, c'était avoidably déroutant, toujours. EnvisagerString
littéraux.Je pense que vous avez répondu à votre propre question: il est redondant.
Set offre Set#contains (Object o) qui fournit l'équivalent de l'identité de test de votre choix à l'Ensemble#get(Object o) et retourne un booléen, comme on pourrait l'attendre.
get()
méthode qui retourne l'objet à l'intérieur du jeu, pas un booléen.