ConcurrentMapperHashMap extends AbstractMap<K, V> implements ConcurrentMap<K, V>, Serializable { @Override public V computeIfAbsent( K key, Function<? super K, ? extends V> mappingFunction) { if (key == null) { throw new NullPointerException("Key is null"); } if (mappingFunction == null) { throw new NullPointerException("Mapping function is null"); } while (true) { IK innerKey = mapKey(key); boolean[] added = {false}; Object[] valueHolder = new Object[1]; IV innerValue = innerConcurrentMap.computeIfAbsent( innerKey, iKey -> { V value = mappingFunction.apply(key); if (value == null) { return null; } added[0] = true; valueHolder[0] = value; return mapValue(key, value); }); if (!added[0]) { unmapKey(innerKey); } if (innerValue == null) { return null; } if (valueHolder[0] != null) { return (V)valueHolder[0]; } V value = unmapValueForQuery(innerValue); if (value == null) { innerConcurrentMap.remove(innerKey, innerValue); } else { return value; } } } protected  ConcurrentMapperHashMap(
		ConcurrentMap<IK, IV> innerConcurrentMap); @Override void clear(); @Override V compute(
		K key,
		BiFunction<? super K, ? super V, ? extends V> remappingFunction); @Override V computeIfAbsent(
		K key, Function<? super K, ? extends V> mappingFunction); @Override V computeIfPresent(
		K key,
		BiFunction<? super K, ? super V, ? extends V> remappingFunction); @Override boolean containsKey(Object key); @Override boolean containsValue(Object value); @Override Set<Entry<K, V>> entrySet(); @Override V get(Object key); @Override boolean isEmpty(); @Override Set<K> keySet(); @Override V put(K key, V value); @Override void putAll(Map<? extends K, ? extends V> map); @Override V putIfAbsent(K key, V value); @Override V remove(Object key); @Override boolean remove(Object key, Object value); @Override V replace(K key, V value); @Override boolean replace(K key, V oldValue, V newValue); @Override int size(); @Override Collection<V> values();  }
@Test public void testComputeIfAbsent() { try { _concurrentMap.computeIfAbsent(null, null); Assert.fail("Should throw NullPointerException"); } catch (NullPointerException nullPointerException) { Assert.assertEquals( "Key is null", nullPointerException.getMessage()); } try { _concurrentMap.computeIfAbsent(_testKey, null); Assert.fail("Should throw NullPointerException"); } catch (NullPointerException nullPointerException) { Assert.assertEquals( "Mapping function is null", nullPointerException.getMessage()); } Assert.assertNull( _concurrentMap.computeIfAbsent(_testKey, key -> null)); _assertEventQueue(Event.MAP_KEY, Event.UNMAP_KEY); Assert.assertSame( _testValue1, _concurrentMap.computeIfAbsent(_testKey, key -> _testValue1)); _assertEventQueue(Event.MAP_KEY, Event.MAP_VALUE); Assert.assertSame( _testValue1, _concurrentMap.computeIfAbsent(_testKey, key -> _testValue2)); _assertEventQueue( Event.MAP_KEY, Event.UNMAP_KEY, Event.UNMAP_VALUE_FOR_QUERY); Assert.assertSame(_testValue1, _concurrentMap.get(_testKey)); _assertEventQueue(Event.MAP_KEY_FOR_QUERY, Event.UNMAP_VALUE_FOR_QUERY); ConcurrentMap<KeyReference, ValueReference> innerConcurrentMap = ReflectionTestUtil.getFieldValue( _concurrentMap, "innerConcurrentMap"); Assert.assertEquals( innerConcurrentMap.toString(), 1, innerConcurrentMap.size()); Collection<ValueReference> valueReferences = innerConcurrentMap.values(); Iterator<ValueReference> iterator = valueReferences.iterator(); ValueReference valueReference = iterator.next(); ReflectionTestUtil.setFieldValue(valueReference, "_value", null); Assert.assertSame( _testValue2, _concurrentMap.computeIfAbsent(_testKey, key -> _testValue2)); _assertEventQueue( Event.MAP_KEY, Event.UNMAP_KEY, Event.UNMAP_VALUE_FOR_QUERY, Event.MAP_KEY, Event.MAP_VALUE); }