2010-04-30 6 views
2

Basic Java question ici d'un vrai débutant. J'ai un ensemble d'objets Java (de classe "MyClass") qui implémentent une certaine interface (Interface "MyIfc"). J'ai un ensemble de ces objets stockés dans une variable privée dans ma classe qui est déclaré comme suit:Quel est le meilleur moyen de convertir un ensemble d'objets Java en un autre ensemble d'objets?

protected Set<MyClass> stuff = new HashSet<MyClass>(); 

J'ai besoin de fournir une méthode publique qui renvoie cet ensemble comme une collection d'objets de type « MyIfc ».

public Collection<MyIfc> getMyStuff() {...} 

Comment effectuer la conversion? La ligne suivante me donne une erreur qu'il ne peut pas faire la conversion. J'aurais deviné que le compilateur savait que les objets de la classe MyClass implémentaient MyIfc et l'auraient donc traité.

Collection<MyIfc> newstuff = stuff; 

Tout éclaircissement est apprécié.

+1

Pourquoi ne pas retourner 'Collection '? –

Répondre

6

probablement la façon la plus correcte est:

return new HashSet<MyIfc>(stuff); 

Si la classe est trop grand pour le faire, vous pouvez le faire:

return Collections.unmodifiableSet(stuff); 
+0

Cela a les mêmes avantages que l'approche de Nathan ci-dessus, mais le fait en une ligne via le constructeur par opposition à l'appel "addAll". Pour cette raison, je pense que c'est la meilleure réponse. – HDave

1

Vous n'avez besoin d'effectuer aucune conversion. Vous devrez taper votre stuff en tant que Set<MyIfc>. Fond: Oui, il est correct que si vous avez un objet de type MyClass, il sera aussi utilisable comme instance MyIfc. Mais vous avez tapé explicitement votre Set en tant que type MyClass. Et c'est simplement quelque chose de différent d'un ensemble de type MyIfc. Après tout, vous pouvez également avoir d'autres classes qui implémentent MyIfc et vous pouvez également les mettre dans votre Set<MyIfc> mais pas dans Set<MyClass>.

+0

Ce serait une bonne idée si je ne pouvais pas traiter les membres du HashSet comme MyClass. Cependant, dans mon cas, je dois le faire, donc je préfère laisser la collection interne telle qu'elle est. – HDave

3

Le compilateur n'aime pas votre affectation de stuff à newstuff, car il ouvre la possibilité de mettre des choses dans newstuff qui implémentent MyIfc mais ne sont pas de type MyClass. Vous pourriez avoir votre getter créer sa propre collection:

public Collection<MyIfc> getMyStuff() { 
    Collection<MyIfc> coll = new HashSet<MyIfc>(); 
    coll.addAll(myStuff); 
    return coll; 
} 
+0

J'aime cette approche car je garde la collection de MyClass - dans ce cas, je dois parfois travailler avec eux comme MyClass. – HDave

0

Google collections définir un groupe d'adaptateurs paresseux, qui peuvent convenir à vos besoins.

Un en particulier est Collections2.transform. Voici un exemple d'adaptation de votre collection:

Collection<MyIfc> newStuff = 
    Collections2.transform(
    stuff, 
    new Function<MyClass, MyIfc>() 
    { 
     public MyIfc apply (final MyClass from) 
     { 
     return (MyIfc) from; // This may throw a ClassCastException though 
     } 
    } 
) 
+0

On dirait une utilisation très étrange de transformer pour moi. Pourquoi ne pas utiliser des choses comme un «Set » en interne. Et beweare votre code retournera une vue en direct qui * n'autorise pas * ajouter/ajouterAll. – whiskeysierra

+0

Je suis d'accord, ça n'a pas de sens de faire tout ça. –

Questions connexes