2010-09-27 18 views
7

Ceci est une question de programmation triviale. Je ne suis pas un expert en Java. Dis-je utiliser des objets de classes personnalisées société et les employés, d'une manière similaire à ce que beaucoup de SGBDR exemples font:Peut-on contrôler l'identité des objets dans Java, et si oui, comment?

class Employee 
{ 
    Company company; 
} 

class Company 
{ 
    String name; 
} 

je dois garantir que les différents objets Company ont des noms uniques - dire pas deux de ces objets peuvent avoir le même nom, parce que de mon point de vue cela n'a pas de sens, et mange aussi simplement de la mémoire - si deux employés travaillent chez IBM, alors il y a un seul objet Company avec cette période . Mes pensées vont maintenant faire Company constructeur privé - de sorte que le travail d'allocation des objets de la Société avec des noms arbitraires est délégué à une méthode de confiance - qui, par exemple, rejettera toute tentative ultérieure de créer un objet avec un nom qui existe déjà ou renvoie un objet existant ou nouveau (en créer un si nécessaire).

Le problème est, je ne suis pas sûr de savoir comment l'accomplir avec élégance. Une chose qui serait bien de ne pas avoir à faire une recherche O(n) chaque fois qu'un objet Company avec un nom est demandé - alors peut-être une carte de hachage ou un arbre binaire est là pour mon confort? Je voudrais également remplacer la façon dont les objets Company sont identifiés - ce qui m'amène à ceci: vais-je surcharger Object.equals et/ou Object.hashCode méthodes?

+0

Etes-vous sûr que vous devriez être préoccupé par l'utilisation de la mémoire supplémentaire? Vous devrez payer pour garder une trace de toutes les entreprises en quelque sorte, et cela vous coûtera (probablement dans le processeur). Assurez-vous que votre optimisation n'est pas prématurée. – nojo

+0

Ce n'est pas forcément tant pour l'optimisation que pour l'importance de la contrainte que deux objets 'Company' du même nom doivent être évités. De cette façon, si, par exemple, la société référencée par N employés change de nom, je dois seulement le faire pour un objet 'Company'. Des trucs comme ça. – amn

Répondre

4

Vous pouvez remplacer equals et hashCode et les stocker dans un HashMap ou HashSet.

+0

comment les chercheriez-vous? –

+0

@Michael: voir le modèle de poids mouche mentionné ci-dessous. – aperkins

+0

@Michael Mon idée de base était qu'elle permettrait toutes sortes d'utilisations qui pourraient être naturelles, comme 'map.get (company)' ou 'set.contains (company)'. –

8

Jetez un coup d'œil au motif de la mouche.

Ce que je voudrais faire est quelque chose comme:

// incomplete, but you get the idea hopefully 
CompanyFactory 
{ 
    private Map<String, Company> companies; 

    public getCompany(final String name) 
    { 
     Company company; 

     company = compaines.get(name); 

     if(company == null) 
     { 
      company = new Company(name); 
      companies.put(name, company); 
     } 

     return (company); 
    } 
} 
+0

+1 - Ceci est le problème exact que le modèle poids plume a été conçu pour résoudre. :) – aperkins

+0

Oui, c'est ce que j'ai commencé à faire. Cependant, je suis préoccupé par les références aux objets Company - il semble que cette carte, bien qu'utile ici, conservera les références à tous les objets Company créés, même s'il n'y a plus de "bonnes" références à ces objets. Je pense à un WeakHashMap, mais les faibles Fait référence aux clés, pas les valeurs. »- ( – amn

+0

Je crois que lorsque la clé est retirée de la WeakHashMap la valeur est également supprimée, et est éligible pour la collecte des ordures – TofuBeer

1

Une chose qui serait bien n'est pas avoir à faire un O (n) rechercher chaque fois un objet de l'entreprise avec un nom est demandé - alors peut-être une carte de hachage ou un arbre binaire est là pour ma commodité ?

Cela semble juste, oui.

Je voudrais aussi passer outre la façon dont les objets société sont identifiés - qui me conduit à ceci: je serai prépondérants Object.equals et/ou méthodes de Object.hashCode?

Si vous assurer qu'il n'y a jamais deux cas avec la même valeur de clé, vous fait ne pas doivent faire.

1

Lorsque je veux créer une collection d'objets qui peuvent être regardés par des noms uniques, je stocke un Map de chaînes (noms) à des objets. Je peux alors chercher l'objet lié à un nom. À strictement parler, vous n'avez pas besoin d'appuyer sur equals() et hashCode() pour ce faire, car vous ne stockez pas vos objets en tant que clés.Implémenter equals() et hashCode() correctement peut être difficile à obtenir correctement, et les clés dans une implémentation de Map comme HashMap (qui peut vous donner des recherches efficaces) sont sensibles à ces méthodes. L'utilisation de la classe String existante (et fondamentalement immuable) en tant que clés vous aide à obtenir cette fonctionnalité de recherche correcte. Mise à jour: Si vous rendez votre constructeur privé, comme vous l'avez mentionné, vous pouvez empêcher la création de nouvelles instances de la société. Fournir une autre méthode de création d'instances de la société (Factory pattern) permet de s'assurer que les nouvelles instances de la société ne sont réellement nouvelles que si elles ne sont pas déjà stockées par nom, sinon l'instance existante est retournée (exemple de Singleton)

+0

En fait, stocker une chaîne comme clé n'est pas mathématiquement suffisant. Il est mathématiquement possible pour 2 chaînes différentes de hacher à la même valeur. –

+5

... qui les met dans le même compartiment, et la méthode String equals() prend le relais pour assurer l'unicité ...? – Brabster

+0

@John En fait, c'est suffisant. – EJP

0

Si le nom d'un objet peut changer avec le temps, envisagez d'inclure un ID unique généré pour chaque objet. Votre mappage serait du nom à l'ID unique, puis de l'ID unique à l'objet réel.

Par ailleurs, si les objets étaient tous connus au moment de la compilation, vous pouvez utiliser un Enum.