ConcurrentMapBasedToIntBiFunctionMemoizer extends ConcurrentMapBasedMemoizer<KEY, Integer> implements ToIntBiFunction<FIRST, SECOND> { @Override public int applyAsInt(final FIRST t, final SECOND u) { final KEY key = keyFunction.apply(t, u); return computeIfAbsent(key, givenKey -> Integer.valueOf(function.applyAsInt(t, u))).intValue(); } @SuppressWarnings(CompilerWarnings.NLS)  ConcurrentMapBasedToIntBiFunctionMemoizer(
            final ConcurrentMap<KEY, Integer> cache,
            final BiFunction<FIRST, SECOND, KEY> keyFunction,
            final ToIntBiFunction<FIRST, SECOND> function); @Override int applyAsInt(final FIRST t, final SECOND u);  }
@Test public void shouldMemoizeBiFunction() { final ConcurrentMap<String, Integer> cache = new ConcurrentHashMap<>(); final BiFunction<String, String, String> keyFunction = (a, b) -> "key"; final ToIntBiFunction<String, String> biFunction = (a, b) -> 123; final ConcurrentMapBasedToIntBiFunctionMemoizer<String, String, String> memoizer = new ConcurrentMapBasedToIntBiFunctionMemoizer<>( cache, keyFunction, biFunction); memoizer.applyAsInt("123.456", "789.123"); }
@Test public void shouldUseSetCacheKeyAndValue() { final ConcurrentMap<String, Integer> cache = new ConcurrentHashMap<>(); final BiFunction<String, String, String> keyFunction = (a, b) -> "key"; final ToIntBiFunction<String, String> biFunction = (a, b) -> 123; final ConcurrentMapBasedToIntBiFunctionMemoizer<String, String, String> memoizer = new ConcurrentMapBasedToIntBiFunctionMemoizer<>( cache, keyFunction, biFunction); memoizer.applyAsInt("123.456", "789.123"); 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()); Assert.assertEquals("Memoization value does not match expectations", 123, memoizer.viewCacheForTest().values().iterator().next().intValue()); }
@Test @SuppressWarnings(CompilerWarnings.UNCHECKED) public void shouldUseCallWrappedBiFunction() { final ConcurrentMap<String, Integer> cache = new ConcurrentHashMap<>(); final BiFunction<String, String, String> keyFunction = (a, b) -> "key"; final ToIntBiFunction<String, String> biFunction = Mockito.mock(ToIntBiFunction.class); final ConcurrentMapBasedToIntBiFunctionMemoizer<String, String, String> memoizer = new ConcurrentMapBasedToIntBiFunctionMemoizer<>( cache, keyFunction, biFunction); memoizer.applyAsInt("123.456", "789.123"); Mockito.verify(biFunction).applyAsInt("123.456", "789.123"); }
@Test public void shouldUseReturnBiFunctionResult() { final ConcurrentMap<String, Integer> cache = new ConcurrentHashMap<>(); final BiFunction<String, String, String> keyFunction = (a, b) -> "key"; final ToIntBiFunction<String, String> biFunction = (a, b) -> 123; final ConcurrentMapBasedToIntBiFunctionMemoizer<String, String, String> memoizer = new ConcurrentMapBasedToIntBiFunctionMemoizer<>( cache, keyFunction, biFunction); Assert.assertEquals(123, memoizer.applyAsInt("123.456", "789.123")); }