/** * If the given key is mapped to the given old value, replaces that value with the given new value. * Otherwise does nothing. A null {@code value} argument removes the entry if the condition matches. * If a value is under computation in another thread, then this method unconditionally returns {@code false}. * * @param key key of the value to replace. * @param oldValue previous value expected to be mapped to the given key. * @param newValue the new value to put if the condition matches, or {@code null} for removing the mapping. * @return {@code true} if the value has been replaced, {@code false} otherwise. * * @since 1.0 */ @Override public boolean replace(final K key, final V oldValue, final V newValue) { ensureValidType(newValue); final boolean done; if (oldValue != null) { done = (newValue != null) ? map.replace(key, oldValue, newValue) : map.remove(key, oldValue); } else { done = (newValue != null) && map.putIfAbsent(key, newValue) == null; } if (done) { notifyChange(key, newValue); } return done; }
/** * If the given key is mapped to any value, replaces that value with the given new value. * Otherwise does nothing. A null {@code value} argument removes the entry. * If a different value is under computation in another thread, then the other thread may fail with * an {@link IllegalStateException} unless {@link #isKeyCollisionAllowed()} returns {@code true}. * * @param key key of the value to replace. * @param value the new value to use in replacement of the previous one, or {@code null} for removing the mapping. * @return the value previously mapped to the given key, or {@code null} if no value existed before this * method call or if the value was under computation in another thread. * * @see #replace(Object, Object, Object) * * @since 1.0 */ @Override public V replace(final K key, final V value) { ensureValidType(value); final Object previous = (value != null) ? map.replace(key, value) : map.remove(key); if (previous != null) { // A null value means that 'replace' did nothing. notifyChange(key, value); } return immediateValueOf(previous); }
/** * Puts the given value in cache and immediately returns the old value. * A null {@code value} argument removes the entry. If a different value is under computation in another thread, * then the other thread may fail with an {@link IllegalStateException} unless {@link #isKeyCollisionAllowed()} * returns {@code true}. For more safety, consider using {@link #putIfAbsent putIfAbsent(…)} instead. * * @param key the key to associate with a value. * @param value the value to associate with the given key, or {@code null} for removing the mapping. * @return the value previously mapped to the given key, or {@code null} if no value existed before this * method call or if the value was under computation in another thread. * * @see #get(Object) * @see #putIfAbsent(Object, Object) */ @Override public V put(final K key, final V value) { ensureValidType(value); final Object previous = (value != null) ? map.put(key, value) : map.remove(key); if (previous != value) { notifyChange(key, value); } return immediateValueOf(previous); }
/** * If no value is already mapped and no value is under computation for the given key, puts the given value * in the cache. Otherwise returns the current value (potentially blocking until the computation finishes). * A null {@code value} argument is equivalent to a no-op. Otherwise a {@code null} return value means that * the given {@code value} has been stored in the {@code Cache}. * * @param key the key to associate with a value. * @param value the value to associate with the given key if no value already exists, or {@code null}. * @return the existing value mapped to the given key, or {@code null} if none existed before this method call. * * @see #get(Object) * @see #computeIfAbsent(Object, Function) * * @since 1.0 */ @Override public V putIfAbsent(final K key, final V value) { if (value == null) { return null; } ensureValidType(value); final Object previous = map.putIfAbsent(key, value); if (previous == null) { // A non-null value means that 'putIfAbsent' did nothing. notifyChange(key, value); } return valueOf(previous); }