I was unable to find any issue or discussion related to what I described below and so decided to create a ticket.

After change 73e382fa877f80994817a136b0adcc4365ccd904 `LocalCache` implements its own versions of methods like `computeIfAbsent` and `computeIfPresent`. These replace previous implementations inherited from `ConcurrentMap` with ones that delegate to unconditional call to `compute` with customised lambda e.g. `computeIfAbsent`:

```java
 return ((v = get(key)) == null &&
                (newValue = mappingFunction.apply(key)) != null &&
                (v = putIfAbsent(key, newValue)) == null) ? newValue : v;
```
becomes:

```java
compute(key, (k, oldValue) -> (oldValue == null) ? function.apply(key) : oldValue);
```

This has side effect that even if value is already present it is replaced by itself which confuses removal listener that will report value being removed with `RemovalCause.REPLACED`. Stats are possibly also incorrect (not used them to date so I am not sure).

Below test case reproduces this behaviour.

```java
List<RemovalNotification> notifications = new ArrayList<>();

Cache<Integer, Integer> cache = CacheBuilder.<Integer, Integer>newBuilder()
        .removalListener((RemovalListener<Integer, Integer>) notifications::add)
        .recordStats()
        .build();

cache.asMap().computeIfAbsent(1, integer -> integer + 1);
cache.asMap().computeIfAbsent(1, integer -> integer + 1);

assert notifications.size() == 1;
assert notifications.get(0).getCause() == RemovalCause.REPLACED;
assert cache.stats().evictionCount() == 0;
assert cache.stats().loadCount() == 2;
```
static class Segment<K, V> extends ReentrantLock {
    /*
     * TODO(fry): Consider copying variables (like evictsBySize) from outer class into this class.
     * It will require more memory but will reduce indirection.
     */
    /*
     * Segments maintain a table of entry lists that are ALWAYS kept in a consistent state, so can
     * be read without locking. Next fields of nodes are immutable (final). All list additions are
     * performed at the front of each bin. This makes it easy to check changes, and also fast to
     * traverse. When nodes would otherwise be changed, new nodes are created to replace them. This
     * works well for hash tables since the bin lists tend to be short. (The average length is less
     * than two.)
     *
     * Read operations can thus proceed without locking, but rely on selected uses of volatiles to
     * ensure that completed write operations performed by other threads are noticed. For most
     * purposes, the "count" field, tracking the number of elements, serves as that volatile
     * variable ensuring visibility. This is convenient because this field needs to be read in many
     * read operations anyway:
     *
     * - All (unsynchronized) read operations must first read the "count" field, and should not look
     * at table entries if it is 0.
     *
     * - All (synchronized) write operations should write to the "count" field after structurally