J'ai un Map<String, List<String>>
dans mon code, dans lequel j'éviterais les pointeurs nuls potentiels si la méthode #get()
de la carte renvoyait une liste vide au lieu de null. Y a-t-il quelque chose comme ça dans l'API Java? Devrais-je simplement prolonger HashMap
?
La réponse de @ Jon est un bon moyen de faire ce que vous demandez directement.
Mais, ce qui me frappe, c’est que vous essayez peut-être de mettre en place une "carte multiple"; c'est-à-dire un mappage d'une clé à une collection de valeurs. Si tel est le cas, vous devriez également consulter les classes à cartes multiples des collections Guava ou Apache commons.
Regarder:
com.google.common.collect.Multimap
et ses implémentations, ouorg.Apache.commons.collections.MultiMap
et ses implémentations. org.Apache.commons.collections4.MultiMap
et ses implémentations (une nouvelle version du précédent MultiMap; introduite dans la v4).Grâce aux méthodes default
, Java 8 est désormais intégré à Map::getOrDefault
:
Map<Integer, String> map = ...
map.put(1, "1");
System.out.println(map.getOrDefault(1, "2")); // "1"
System.out.println(map.getOrDefault(2, "2")); // "2"
Comme indiqué dans les commentaires:
Le concept de carte informatique de Guava a été remplacé par
LoadingCache
. De plus, Java 8 a introduit l'interface de carte NicecomputeIfAbsent
méthode par défaut qui ne rompt pas le contrat de carte et offre une évaluation paresseuse.
Guava a eu l'idée d'une "carte informatique" qui exécutera une fonction pour fournir une valeur si elle n'est pas présente. Il a été implémenté dans MapMaker.makeComputingMap
; vous pouvez maintenant utiliser CacheBuilder
- voir CacheBuilder.build
pour plus de détails.
Cela peut être exagéré pour ce que vous recherchez - vous feriez peut-être mieux d'écrire une implémentation Map
dont a a Map
(en utilisant la composition plutôt que d'étendre une implémentation particulière), puis de renvoyer le défaut si ce n'est présent. Toute méthode autre que get
pourrait probablement simplement déléguer à une autre carte:
public class DefaultingMap<K, V> implements Map<K, V>
{
private final Map<K, V> map;
private final V defaultValue;
public DefaultingMap(Map<K, V> map, V defaultValue)
{
this.map = map;
this.defaultValue = defaultValue;
}
@Override public V get(Object key)
{
V ret = map.get(key);
if (ret == null)
{
ret = defaultValue;
}
return ret;
}
@Override public int size()
{
return map.size();
}
// etc
}
Similaire aux publications précédentes, sauf que vous pouvez simplement remplacer la méthode get si vous souhaitez modifier son comportement.
Map<String, List<String>> map = new LinkedHashMap<String, List<String>>() {
public String get(Object key) {
List<String> list = super.get(key);
if (list == null && key instanceof String)
super.put(key, list = new ArrayList<String>());
return list;
}
};
Guava a une méthode pour faire exactement ce que vous voulez. C'est similaire à La réponse d'Argote .
Map<String, List<String>> myMap = ...
Functions.forMap(myMap, Arrays.asList("default", "value"));
Il me semble que vous pouvez simplement écrire une fonction wrapper pour obtenir la valeur souhaitée et, si c'est null
, renvoyer la valeur par défaut à la place.
Map<String, List<String>> myMap = new Map<String, List<String>>();
public List<String> myGet(String key) {
List<String> ret = myMap.get(key);
if(ret == NULL) {
return defaultList(); // where defaultList is a function that generates your default list.
}
return ret;
}
Cela suppose que votre myMap
est une variable globale (par souci de simplicité). Si ce n'est pas ce que vous voulez, vous pouvez également étendre Map
ou HashMap
à quelque chose comme MyMap
et simplement inclure cette fonction supplémentaire. De cette façon, vous pouvez l'utiliser depuis n'importe quel endroit où un objet MyMap
est instancié.