@Override public boolean equals(final Object o) { if (o == this) { return true; } if (o == null) { return false; } if (o instanceof ImmutableOffsetMap) { final ImmutableOffsetMap<?, ?> om = (ImmutableOffsetMap<?, ?>) o; if (newKeys.isEmpty() && offsets == om.offsets() && Arrays.deepEquals(objects, om.objects())) { return true; } } else if (o instanceof MutableOffsetMap) { final MutableOffsetMap<?, ?> om = (MutableOffsetMap<?, ?>) o; if (offsets == om.offsets && Arrays.deepEquals(objects, om.objects) && newKeys.equals(om.newKeys)) { return true; } } else if (o instanceof Map) { final Map<?, ?> om = (Map<?, ?>) o; // Size and key sets have to match if (size() != om.size() || !keySet().equals(om.keySet())) { return false; } try { // Ensure all newKeys are present. Note newKeys is guaranteed to // not contain null value. for (Entry<K, V> e : newKeys.entrySet()) { if (!e.getValue().equals(om.get(e.getKey()))) { return false; } } // Ensure all objects are present for (Entry<K, Integer> e : offsets.entrySet()) { final Object obj = objects[e.getValue()]; if (!NO_VALUE.equals(obj)) { final V v = objectToValue(e.getKey(), obj); if (!v.equals(om.get(e.getKey()))) { return false; } } } } catch (ClassCastException e) { // Can be thrown by om.get() and indicate we have incompatible key types return false; } return true; } return false; }
protected MutableOffsetMap(final ImmutableOffsetMap<K, V> m) { this.offsets = m.offsets(); this.objects = m.objects(); this.newKeys = new LinkedHashMap<>(); }