ConcurrentMapBasedBiPredicateMemoizer extends ConcurrentMapBasedMemoizer<KEY, Boolean> implements BiPredicate<FIRST, SECOND> { @Override public boolean test(final FIRST t, final SECOND u) { final KEY key = keyFunction.apply(t, u); return computeIfAbsent(key, givenKey -> Boolean.valueOf(biPredicate.test(t, u))).booleanValue(); } @SuppressWarnings(CompilerWarnings.NLS)  ConcurrentMapBasedBiPredicateMemoizer(
            final ConcurrentMap<KEY, Boolean> cache,
            final BiFunction<FIRST, SECOND, KEY> keyFunction,
            final BiPredicate<FIRST, SECOND> biPredicate); @Override boolean test(final FIRST t, final SECOND u);  }
@Test public void shouldMemoizeBiPredicate() { final ConcurrentMap<String, Boolean> cache = new ConcurrentHashMap<>(); final BiFunction<String, String, String> keyFunction = (first, second) -> first + second; final BiPredicate<String, String> biPredicate = (first, second) -> true; final ConcurrentMapBasedBiPredicateMemoizer<String, String, String> memoizer = new ConcurrentMapBasedBiPredicateMemoizer<>( cache, keyFunction, biPredicate); Assert.assertTrue(memoizer.test("first", "second")); }
@Test public void shouldUseSetCacheKeyAndValue() { final ConcurrentMap<String, Boolean> cache = new ConcurrentHashMap<>(); final BiFunction<String, String, String> keyFunction = (first, second) -> first + second; final BiPredicate<String, String> biPredicate = (first, second) -> true; final ConcurrentMapBasedBiPredicateMemoizer<String, String, String> memoizer = new ConcurrentMapBasedBiPredicateMemoizer<>( cache, keyFunction, biPredicate); memoizer.test("first", "second"); Assert.assertEquals("Memoization key does not match expectations", "firstsecond", memoizer.viewCacheForTest().keySet().iterator().next()); Assert.assertTrue("Memoization value does not match expectations", memoizer.viewCacheForTest().values().iterator().next().booleanValue()); }
@Test @SuppressWarnings(CompilerWarnings.UNCHECKED) public void shouldUseCallWrappedBiPredicate() { final ConcurrentMap<String, Boolean> cache = new ConcurrentHashMap<>(); final BiFunction<String, String, String> keyFunction = (first, second) -> first + second; final BiPredicate<String, String> biPredicate = Mockito.mock(BiPredicate.class); final ConcurrentMapBasedBiPredicateMemoizer<String, String, String> memoizer = new ConcurrentMapBasedBiPredicateMemoizer<>( cache, keyFunction, biPredicate); memoizer.test("first", "second"); Mockito.verify(biPredicate).test("first", "second"); }