En lisant des articles intéressants, les gars prétendent que la différence entre les deux fonctions est la suivante:
Les deux fonctions aspirent à ajouter un élément si la clé spécifiée n'est pas déjà présente dans Map.
putIfAbsent ajoute un élément avec la valeur spécifiée, tandis que computeIfAbsent ajoute un élément avec la valeur calculée à l'aide de la clé. http://www.buggybread.com/2014/10/Java-8-difference-between-map.html
Et
Nous avons vu que putIfAbsent supprime le moyen impératif de définir l’instruction if, mais qu’en est-il si le fait de récupérer les articles Java nuit réellement à notre performance?
Pour optimiser cela, nous ne voulons pas aller chercher les articles avant d’être vraiment sûrs d’en avoir besoin - c’est-à-dire qu’il faut savoir si la clé est absente avant d’aller chercher les articles. http://www.deadcoderising.com/2017-02-14-Java-8-declarative-ways-of-modifying-a-map-using-compute-mer-re-replace/
Je ne comprenais pas quelles sont les différences. Pourriez-vous nous en dire plus sur ces deux fonctions?
Différence n ° 1
computeIfAbsent
prend une fonction de mappage, appelée pour obtenir la valeur si la clé est manquante.
putIfAbsent
prend directement la valeur.
Si la valeur est coûteuse à obtenir, putIfAbsent
la gaspille si la clé existe déjà.
Une valeur "chère" courante est par exemple: new ArrayList<>()
pour lorsque vous créez un Map<K, List<V>>
, où créer une nouvelle liste lorsque la clé existe déjà (qui rejette ensuite la nouvelle liste) génère des déchets inutiles.
Différence n ° 2
computeIfAbsent
renvoie "la valeur actuelle (existante ou calculée) associée à la clé spécifiée, ou null si la valeur calculée est null".
putIfAbsent
renvoie "la valeur précédente associée à la clé spécifiée ou la valeur null s'il n'y avait pas de mappage pour la clé".
Ainsi, si la clé existe déjà, ils renvoient la même chose, mais si la clé est manquante, computeIfAbsent
renvoie la valeur calculée, tandis que putIfAbsent
renvoie null.
Différence # 3
Les deux méthodes définissent "absent" car la clé est manquante ou la valeur existante est nulle, mais:
computeIfAbsent
ne mettra pas de valeur nulle si la clé est absente.
putIfAbsent
mettra la valeur si la clé est absente, même si la valeur est null.
Cela ne fait aucune différence pour les prochains appels à computeIfAbsent
, putIfAbsent
et get
appels, mais cela fait une différence pour des appels tels que getOrDefault
et containsKey
.
Supposons que vous ayez un Map<String,ValueClass>
.
map.putIfAbsent("key", new ValueClass());
créera quand même une instance ValueClass
, même si la clé "clé" est déjà dans le Map
. Cela ne ferait que créer une instance inutile.
D'autre part
map.computeIfAbsent("key", k -> new ValueClass());
créera une instance ValueClass
uniquement si la clé "clé" n'est pas déjà dans la variable Map
(ou est mappée sur une valeur null
.).
Par conséquent, computeIfAbsent
est plus efficace.
putIfAbsent
est équivalent à:
ValueClass value = new ValueClass();
if (map.get("key") == null) {
map.put("key",value);
}
tandis que computeIfAbsent
est équivalent à:
if (map.get("key") == null) {
map.put("key",new ValueClass());
}
Une autre petite différence entre les deux méthodes est que computeIfAbsent
ne mettra pas de valeur null
pour une clé absente. putIfAbsent
sera.
Vous pouvez comprendre la différence en regardant attentivement les signatures de la méthode:
putIfAbsent
prend une clé et une valeur et la met dans la carte s'il n'y a pas de valeur pour cette clé dans la carte.computeIfAbsent
prend une clé et un Function
. S'il n'y a pas de valeur pour cette clé dans la carte, la fonction est appelée pour créer la valeur, qui est ensuite placée dans la carte.Si vous avez déjà la valeur, utilisez putIfAbsent
.
Si vous n'avez pas encore la valeur et que la création de la valeur est une opération coûteuse (par exemple, la valeur doit être recherchée dans une base de données), utilisez computeIfAbsent
pour que l'opération coûteuse ne nécessite pas à effectuer si la carte contient déjà une valeur pour la clé spécifiée.
Peut-être que les implémentations par défaut peuvent clarifier un peu plus ...
default V putIfAbsent(K key, V value)
L'implémentation par défaut est équivalente à, pour cette carte:
V v = map.get(key);
if (v == null)
v = map.put(key, value);
return v;
D'autre part:
default V computeIfAbsent(K key,
Function<? super K,? extends V> mappingFunction)
est équivalent à:
if (map.get(key) == null) {
V newValue = mappingFunction.apply(key);
if (newValue != null)
map.put(key, newValue);
}
V putIfAbsent(K key, V value)
- Si la clé spécifiée n'est pas déjà associée à une valeur (ou si elle est mappée sur null), tente de calculer sa valeur à l'aide de la fonction de mappage donnée et la saisit dans cette mappe sauf si la valeur est null.
V computeIfAbsent(K key, Function<? super K,? extends V> mappingFunction)
- Si la clé spécifiée n'est pas déjà associée à une valeur (ou si elle est mappée sur null), tente de calculer sa valeur à l'aide de la fonction de mappage donnée et la saisit dans cette mappe sauf si la valeur est null.
La lecture de la documentation peut vous donner une réponse plus évidente. https://docs.Oracle.com/javase/8/docs/api/Java/util/Map.html