ConcurrentMapBasedDoubleSupplierMemoizer extends ConcurrentMapBasedMemoizer<KEY, Double> implements DoubleSupplier { @Override public double getAsDouble() { return computeIfAbsent(keySupplier.get(), input -> Double.valueOf(supplier.getAsDouble())).doubleValue(); } @SuppressWarnings(CompilerWarnings.NLS)  ConcurrentMapBasedDoubleSupplierMemoizer(
            final ConcurrentMap<KEY, Double> cache,
            final Supplier<KEY> keySupplier,
            final DoubleSupplier supplier); @Override double getAsDouble();  }
@Test public void shouldMemoizeSuppliedValue() { final ConcurrentMap<String, Double> cache = new ConcurrentHashMap<>(); final Supplier<String> keySupplier = () -> "key"; final DoubleSupplier supplier = () -> 123.456D; final ConcurrentMapBasedDoubleSupplierMemoizer<String> memoizer = new ConcurrentMapBasedDoubleSupplierMemoizer<>( cache, keySupplier, supplier); Assert.assertEquals("Memoized value does not match expectations", 123.456D, memoizer.getAsDouble(), 0.0D); }
@Test public void shouldUseSuppliedKey() { final ConcurrentMap<String, Double> cache = new ConcurrentHashMap<>(); final Supplier<String> keySupplier = () -> "key"; final DoubleSupplier supplier = () -> 123.456D; final ConcurrentMapBasedDoubleSupplierMemoizer<String> memoizer = new ConcurrentMapBasedDoubleSupplierMemoizer<>( cache, keySupplier, supplier); Assert.assertTrue("Cache is not empty before memoization", memoizer.viewCacheForTest().isEmpty()); Assert.assertEquals("Memoized value does not match expectations", 123.456D, memoizer.getAsDouble(), 0.0D); Assert.assertFalse("Cache is still empty after memoization", memoizer.viewCacheForTest().isEmpty()); Assert.assertEquals("Memoization key does not match expectations", "key", memoizer.viewCacheForTest().keySet().iterator().next()); }
@Test @SuppressWarnings(CompilerWarnings.BOXING) public void shouldTriggerOnce() { final ConcurrentMap<String, Double> cache = new ConcurrentHashMap<>(); final Supplier<String> keySupplier = () -> "key"; final DoubleSupplier supplier = mock(DoubleSupplier.class); given(supplier.getAsDouble()).willReturn(123.456D); final ConcurrentMapBasedDoubleSupplierMemoizer<String> memoizer = new ConcurrentMapBasedDoubleSupplierMemoizer<>( cache, keySupplier, supplier); Assert.assertEquals("Memoized value does not match expectations", 123.456D, memoizer.getAsDouble(), 0.0D); Assert.assertEquals("Memoized value does not match expectations", 123.456D, memoizer.getAsDouble(), 0.0D); Assert.assertEquals("Memoized value does not match expectations", 123.456D, memoizer.getAsDouble(), 0.0D); Assert.assertEquals("Memoized value does not match expectations", 123.456D, memoizer.getAsDouble(), 0.0D); verify(supplier, times(1)).getAsDouble(); }