43 votes

Pourquoi java.util.Set <V> l'interface ne fournit pas une méthode get (Object o)?

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.

30voto

Dilum Ranatunga Points 7677

Bien que la pureté argument de la méthode de 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 de l'élément dans un ensemble. Peut-être une meilleure façon d'indiquer l'intention est d'avoir une méthode comme

public interface Collection<E> extends ... {
  ...
  public E findMatch(Object o) throws UnsupportedOperationException;
  ...
}

Notez que cette API a une valeur plus large que dans un délai Défini.

Quant à 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 minimum 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é.

13voto

GClaramunt Points 2090

Le problème est le suivant: Set n'est pas pour "obtenir" des objets, mais pour ajouter et tester la présence. Je comprends ce que vous recherchez, j’ai eu une situation similaire et j’ai fini par utiliser une carte du même objet en clé et en valeur.

EDIT: Juste pour clarifier: http://en.wikipedia.org/wiki/Set_(abstract_data_type)

6voto

Val Points 985

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:

class Element {

        public int hashCode() {return sumOfKeyFields()}
        public boolean equals(Object e) {keyField1.equals(e) && keyField2.equals(e) && ..}

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. Les 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:

La plupart de ce chapitre est consacrée à l'étude d'un très simple de recherche problème: comment trouver les données qui ont été stockées avec un d'identification.

Vous voyez, les données sont stocker de l'identification. Pas d'identification de pointage de données, mais les données de l'identification. Il continue:

Par exemple, dans une application numérique, nous pourrions vouloir trouver f(x), x et un tableau de valeurs de f; en un non numérique de l'application, nous pourrions trouver de l'anglais la traduction d'un mot russe.

On dirait qu'il commence à parler de la cartographie. Cependant,

En général, nous supposons qu'un ensemble de N enregistrements ont été conservés, et le problème est de trouver celui qui convient le mieux. Nous demandons généralement la N de clés distinctes, de sorte que chaque clé identifie de manière unique son record. La collection de tous les dossiers est appelé un tableau ou un fichier, où le mot "table" est généralement utilisé pour indiquer un fichier de petite taille, et "fichier" est généralement utilisé pour indiquer une grande table. Un gros fichier ou un groupe de fichiers est souvent appelée une base de données.

Les algorithmes de recherche sont présentés avec un soi-disant argument, K, et le problème est de trouver le dossier qui a K comme sa clé. Bien que l' l'objectif de la recherche est de trouver l'information stockée dans l'enregistrement associé avec K, les algorithmes de ce chapitre généralement ignorer tout, mais les touches elles-mêmes. Dans la pratique, nous pouvons trouver la de données associées, une fois que nous avons situé K; par exemple, si K apparaît dans emplacement TABLE + i, les données associées (ou un pointeur) peut être dans un endroit TABLEAU + i + 1

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.

Il nous est donné de N éléments à trier; nous les appelons des dossiers, et l'ensemble de la collection de N enregistrements sera appelé un fichier. Chaque enregistrement Rj a une clé Kj, qui régit le processus de tri. Supplémentaires données, en plus de la clé, est aussi le plus souvent; cela extra "par satellite l'information" n'a aucun effet sur le tri, sauf qu'il doit être transporté le long de dans le cadre de chaque enregistrement.

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]

ensemble entité est de la collecte ou de l'ensemble de toutes les entités d'un type d'entité [http://wiki.answers.com/Q/What_is_entity_and_entity_set_in_dbms] Les objets de la classe unique de partager leurs attributs de classe. De même, faire des enregistrements dans la base de données. Ils partagent les attributs de colonne.

Un cas particulier d'une collection est une étendue de la classe, qui est la collection de tous les objets appartenant à la classe. Classe extensions permettent les classes à être traités comme des relations

... ["Système de base de données de Concepts", 6e Édition]

Fondamentalement, la 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 pour obtenir la méthode)

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 - là doit être la 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:

  1. la carte est inutile quand on a un ensemble d'objets uniques
  2. carte introduit de la redondance dans l'Exécution de stockage
  3. carte de la présente augmentation du code dans la base de données (dans les Collections)
  4. à l'aide de la carte contredit le stockage de données, normalisation

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é le Déc 2013: SICP dit aussi que DB est un jeu avec un détrompeur dossiers plutôt que d'une carte:

Un classique de données-système de gestion de la dépense une grande quantité de temps d'accéder ou de modifier les données dans les dossiers et nécessite donc une méthode efficace pour l'accès aux dossiers. Ceci est fait par l'identification de une partie de chaque enregistrement pour servir d'identification de la clé. Maintenant que nous représentons la base de données comme un ensemble d'enregistrements.

1voto

Oz. Points 656

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.

1voto

Sorin Mocanu Points 700

Donc, je comprends que vous pourriez avoir deux objets égaux, mais ils ne sont pas de la même instance.

Comme

Integer a = new Integer(3);
Integer b = new Integer(3);

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X