J'ai un HashMap appelé map en tant que membre, et j'en récupère les valeurs en utilisant:
var t = x.<Zoom>get("foo")
Je pense que je peux transformer cela en quelque chose en utilisant des génériques afin que nous puissions convertir la valeur de retour en ligne , quelque chose comme ceci:
var t = (Zoom)x.get("foo");
mais cela ne compile pas. En gros, au lieu de faire ceci:
public V get(String s) { return (V)this.map.get(s); }
il pourrait être agréable d'utiliser:
public Object get(String s) { return this.map.get(s); }
mais je ne suis pas sûr si quelque chose comme ça est possible.
4 Réponses :
Ahhh je pense que cela fonctionne:
public <V> V get(String s) { return (V)this.map.get(s); }
bien sûr, je reçois cet avertissement:
Tant que la carte est
, je pense que c'est une mauvaise conception.
Ok, si c'est une mauvaise conception, comment puis-je l'améliorer? C'est pourquoi j'ai posté l'OP, pour des conseils plus que tout
Vous pouvez également transmettre le type générique au membre HashMap lors de la création et récupérer le type correct sans conversion.
class ClassUsingHashMap<T>{ private HashMap<String, T> map = new HashMap<String, T>() }
Vous devriez également rendre votre HashMap
générique en rendant la classe entière générique:
class MyClass<V> { private Map<String, V> map = new HashMap<>(); public V get(String s) { return this.map.get(s); } }
Vote positif, mais dans mon cas, tous les types de la carte ne seront pas de type V, les valeurs de la carte peuvent être n'importe quoi, donc V est juste un objet ici
Les types partagent-ils un supertype commun autre que Object? Si tel est le cas, créez la définition MyClass
et effectuez votre casting final en dehors de ce code
Ils ne partagent pas un super type commun autre que Object
@MrCholo S'ils ne partagent pas un type commun, tous les objets doivent-ils être dans la même carte? Vos exemples donnent l'impression que vous devez de toute façon connaître le type de valeur de chaque clé, alors peut-être pourriez-vous simplement les stocker dans différentes cartes pour la sécurité du type
@MrCholo: s'ils ne partagent pas un super type, de quoi parle la collection? Comment nommez-vous cela? S'agit-il de "des objets que je souhaite conserver pour une utilisation ultérieure" ou de "ma collection d'objets globalement accessible"? Pensez à ceci: stockez-vous tous vos objets, par exemple le beurre et vos vêtements au même endroit, par ex. le four et puis vous les appelez par leur nom pour les obtenir? C'est ce que vous avez mis en œuvre.
Si vous ne connaissez pas le type de valeurs au préalable, vous pouvez passer des informations de type avec un objet Class
:
public class MapContainer<T> { private Map<String, T> map = new HashMap<>(); public T get(String s) { return this.map.get(s); } }
Et ensuite, faites simplement p >
Integer intValue = container.get("key", Integer.class);
Mais cela explosera avec une ClassCastException
si la valeur stockée par "key" n'est pas un Integer
, donc vous auriez d'être très prudent.
Mais si vous connaissez le type de valeur à l'avance, c'est juste
public class MapContainer { private Map<String, Object> map = new HashMap<>(); public <V> V get(String s, Class<V> classOfValue) { Object value = this.map.get(s); return classOfValue.cast(value); } }
Quelle est la définition de la carte? quel type y a-t-il?
le champ / membre de la carte est comme si
la carte HashMap finale publique;
Pourquoi votre type de valeur est-il
Object
? Et pas un générique?@JoeC eh bien j'essaye de le rendre générique, n'est-ce pas? Je ne comprends pas bien
Par générique, j'entends au sens Java (c'est-à-dire
HashMap
).@JoeC oui c'est ce que j'essayais de faire, je l'ai compris après avoir posté, voir ma réponse
Avoir un objet concret, au lieu de
Map
, l'interface a déjà une implémentation générique
simplement le lier à de meilleurs types aiderait.