/** * This method is a convenience for testing. Code should call {@link LocalCache#containsValue} * directly. */ @VisibleForTesting boolean containsValue(Object value) { try { if (count != 0) { // read-volatile long now = map.ticker.read(); AtomicReferenceArray<ReferenceEntry<K, V>> table = this.table; int length = table.length(); for (int i = 0; i < length; ++i) { for (ReferenceEntry<K, V> e = table.get(i); e != null; e = e.getNext()) { V entryValue = getLiveValue(e, now); if (entryValue == null) { continue; } if (map.valueEquivalence.equivalent(value, entryValue)) { return true; } } } } return false; } finally { postReadCleanup(); } }
private void testItems() { for (T item : items) { /* * TODO(cpovirk): consider no longer running these equivalent() tests on every Equivalence, * since the Equivalence base type now implements this logic itself */ assertTrue(item + " must be inequivalent to null", !equivalence.equivalent(item, null)); assertTrue("null must be inequivalent to " + item, !equivalence.equivalent(null, item)); assertTrue(item + " must be equivalent to itself", equivalence.equivalent(item, item)); assertEquals( "the hash of " + item + " must be consistent", equivalence.hash(item), equivalence.hash(item)); } } }
public void testWrap() { new EqualsTester() .addEqualityGroup( LENGTH_EQUIVALENCE.wrap("hello"), LENGTH_EQUIVALENCE.wrap("hello"), LENGTH_EQUIVALENCE.wrap("world")) .addEqualityGroup(LENGTH_EQUIVALENCE.wrap("hi"), LENGTH_EQUIVALENCE.wrap("yo")) .addEqualityGroup(LENGTH_EQUIVALENCE.wrap(null), LENGTH_EQUIVALENCE.wrap(null)) .addEqualityGroup(Equivalence.equals().wrap("hello")) .addEqualityGroup(Equivalence.equals().wrap(null)) .testEquals(); }
/** * Returns a hash code for {@code t}. * * <p>The {@code hash} has the following properties: * <ul> * <li>It is <i>consistent</i>: for any reference {@code x}, multiple invocations of * {@code hash(x}} consistently return the same value provided {@code x} remains unchanged * according to the definition of the equivalence. The hash need not remain consistent from * one execution of an application to another execution of the same application. * <li>It is <i>distributable accross equivalence</i>: for any references {@code x} and {@code y}, * if {@code equivalent(x, y)}, then {@code hash(x) == hash(y)}. It is <i>not</i> necessary * that the hash be distributable accorss <i>inequivalence</i>. If {@code equivalence(x, y)} * is false, {@code hash(x) == hash(y)} may still be true. * <li>{@code hash(null)} is {@code 0}. * </ul> */ public final int hash(@Nullable T t) { if (t == null) { return 0; } return doHash(t); }
/** * Returns {@code true} if the given objects are considered equivalent. * * <p>The {@code equivalent} method implements an equivalence relation on object references: * * <ul> * <li>It is <i>reflexive</i>: for any reference {@code x}, including null, {@code * equivalent(x, x)} returns {@code true}. * <li>It is <i>symmetric</i>: for any references {@code x} and {@code y}, {@code * equivalent(x, y) == equivalent(y, x)}. * <li>It is <i>transitive</i>: for any references {@code x}, {@code y}, and {@code z}, if * {@code equivalent(x, y)} returns {@code true} and {@code equivalent(y, z)} returns {@code * true}, then {@code equivalent(x, z)} returns {@code true}. * <li>It is <i>consistent</i>: for any references {@code x} and {@code y}, multiple invocations * of {@code equivalent(x, y)} consistently return {@code true} or consistently return {@code * false} (provided that neither {@code x} nor {@code y} is modified). * </ul> */ public final boolean equivalent(@Nullable T a, @Nullable T b) { if (a == b) { return true; } if (a == null || b == null) { return false; } return doEquivalent(a, b); }
@Override public boolean apply(@Nullable T input) { return equivalence.equivalent(input, target); }
/** * This method is a convenience for testing. Code should call {@link * MapMakerInternalMap#containsValue} directly. */ @VisibleForTesting boolean containsValue(Object value) { try { if (count != 0) { // read-volatile AtomicReferenceArray<E> table = this.table; int length = table.length(); for (int i = 0; i < length; ++i) { for (E e = table.get(i); e != null; e = e.getNext()) { V entryValue = getLiveValue(e); if (entryValue == null) { continue; } if (map.valueEquivalence().equivalent(value, entryValue)) { return true; } } } } return false; } finally { postReadCleanup(); } }
@Override protected boolean doEquivalent(F a, F b) { return resultEquivalence.equivalent(function.apply(a), function.apply(b)); }
@Override protected int doHash(Iterable<T> iterable) { int hash = 78721; for (T element : iterable) { hash = hash * 24943 + elementEquivalence.hash(element); } return hash; }
public void testEquivalentTo() { Predicate<Object> equalTo1 = Equivalence.equals().equivalentTo("1"); assertTrue(equalTo1.apply("1")); assertFalse(equalTo1.apply("2")); assertFalse(equalTo1.apply(null)); Predicate<Object> isNull = Equivalence.equals().equivalentTo(null); assertFalse(isNull.apply("1")); assertFalse(isNull.apply("2")); assertTrue(isNull.apply(null)); new EqualsTester() .addEqualityGroup(equalTo1, Equivalence.equals().equivalentTo("1")) .addEqualityGroup(isNull) .addEqualityGroup(Equivalence.identity().equivalentTo("1")) .testEquals(); }
public void testOnResultOf_equals() { new EqualsTester() .addEqualityGroup( Equivalence.identity().onResultOf(Functions.toStringFunction()), Equivalence.identity().onResultOf(Functions.toStringFunction())) .addEqualityGroup(Equivalence.equals().onResultOf(Functions.toStringFunction())) .addEqualityGroup(Equivalence.identity().onResultOf(Functions.identity())) .testEquals(); }
void add(E element) { contents.add(EQUALITY_WITHOUT_USING_HASH_CODE.wrap(element)); }
public void testToImmutableEnumMap() { Collector<Entry<AnEnum, Integer>, ?, ImmutableMap<AnEnum, Integer>> collector = Maps.toImmutableEnumMap(Entry::getKey, Entry::getValue); Equivalence<ImmutableMap<AnEnum, Integer>> equivalence = Equivalence.equals().<Entry<AnEnum, Integer>>pairwise().onResultOf(ImmutableMap::entrySet); CollectorTester.of(collector, equivalence) .expectCollects( ImmutableMap.of(AnEnum.A, 1, AnEnum.C, 2, AnEnum.E, 3), mapEntry(AnEnum.A, 1), mapEntry(AnEnum.C, 2), mapEntry(AnEnum.E, 3)); }
@Override Equivalence<Object> defaultEquivalence() { return Equivalence.identity(); } };
@Override Equivalence<Object> defaultEquivalence() { return Equivalence.equals(); } },
public void testOnResultOf() { EquivalenceTester.of(Equivalence.equals().onResultOf(Functions.toStringFunction())) .addEquivalenceGroup(new IntValue(1), new IntValue(1)) .addEquivalenceGroup(new IntValue(2)) .test(); }