JCacheBasedDoubleBinaryOperatorMemoizer extends AbstractJCacheBasedMemoizer<KEY, Double> implements DoubleBinaryOperator { @Override public double applyAsDouble(final double left, final double right) { final KEY key = keyFunction.apply(left, right); return invoke(key, givenKey -> Double.valueOf(function.applyAsDouble(left, right))).doubleValue(); } JCacheBasedDoubleBinaryOperatorMemoizer(
            final Cache<KEY, Double> cache,
            final DoubleBinaryFunction<KEY> keyFunction,
            final DoubleBinaryOperator function); @Override double applyAsDouble(final double left, final double right);  }
@Test public void shouldMemoizeFunction() { final DoubleBinaryOperator function = (a, b) -> 123.456D; final DoubleBinaryFunction<String> keyFunction = (a, b) -> "key"; try (final Cache<String, Double> cache = JCacheMemoize.createCache(DoubleFunction.class)) { final JCacheBasedDoubleBinaryOperatorMemoizer<String> loader = new JCacheBasedDoubleBinaryOperatorMemoizer<>( cache, keyFunction, function); Assert.assertEquals("Memoized value does not match expectation", 123.456D, loader.applyAsDouble(123.456D, 789.123D), 0.0D); } }
@Test @SuppressWarnings(CompilerWarnings.UNCHECKED) public void shouldWrapRuntimeExceptionInMemoizationException() { final DoubleBinaryFunction<String> keyFunction = (a, b) -> "key"; try (final Cache<String, Double> cache = Mockito.mock(Cache.class)) { final JCacheBasedDoubleBinaryOperatorMemoizer<String> loader = new JCacheBasedDoubleBinaryOperatorMemoizer<>( cache, keyFunction, null); given(cache.invoke(any(), any())).willThrow(RuntimeException.class); thrown.expect(MemoizationException.class); loader.applyAsDouble(123.456D, 789.123D); } }