code: private static <K, V> boolean equivalent(
        @Nullable HamtPMap<K, V> t1,
        @Nullable HamtPMap<K, V> t2,
        BiPredicate<V, V> equivalence) {
      if (t1 == t2) {
        return true;
      } else if (t1 == null || t2 == null) {
        return false;
      }
  
      if (t1.hash != t2.hash) {
        // Due to our invariant, we can safely conclude that there's a discrepancy in the
        // keys without any extra work.
        return false;
      } else if (!t1.key.equals(t2.key)) {
        // Hash collision: try to rearrange t2 to have the same root as t1
        t2 = t2.pivot(t1.key, t1.hash);
        if (t2.key == null) {
          // t1.key not found in t2
          return false;
        }
      }
  
      if (!equivalence.test(t1.value, t2.value)) {
        return false;
      }
      int mask = t1.mask | t2.mask;
      while (mask != 0) {
        int childBit = Integer.lowestOneBit(mask);
        mask &= ~childBit;
        if (!equivalent(t1.getChild(childBit), t2.getChild(childBit), equivalence)) {
          return false;
        }
      }
      return true;
    }
docs: Internal recursive implementation of equivalent(HamtPMap, BiPredicate).