001package io.cui.tools.collect;
002
003import java.util.Map;
004
005/**
006 * An object representing the differences between two maps.
007 *
008 * @author com.google.common.collect.MapDifference
009 * @param <K> identifying the type of the key
010 * @param <V> identifying the type of the value
011 *
012 */
013public interface MapDifference<K, V> {
014
015    /**
016     * @return {@code true} if there are no differences between the two maps; that is, if the maps
017     *         are equal.
018     */
019    boolean areEqual();
020
021    /**
022     * @return an unmodifiable map containing the entries from the left map whose keys are not
023     *         present in the right map.
024     */
025    Map<K, V> entriesOnlyOnLeft();
026
027    /**
028     * @return an unmodifiable map containing the entries from the right map whose keys are not
029     *         present in the left map.
030     */
031    Map<K, V> entriesOnlyOnRight();
032
033    /**
034     * @return an unmodifiable map containing the entries that appear in both maps; that is, the
035     *         intersection of the two maps.
036     */
037    Map<K, V> entriesInCommon();
038
039    /**
040     * @return an unmodifiable map describing keys that appear in both maps, but with different
041     *         values.
042     */
043    Map<K, ValueDifference<V>> entriesDiffering();
044
045    /**
046     * Compares the specified object with this instance for equality. Returns {@code true} if the
047     * given object is also a {@code MapDifference} and the values returned by the {@link
048     * #entriesOnlyOnLeft()}, {@link #entriesOnlyOnRight()}, {@link #entriesInCommon()} and {@link
049     * #entriesDiffering()} of the two instances are equal.
050     */
051    @Override
052    boolean equals(Object object);
053
054    /**
055     * Returns the hash code for this instance. This is defined as the hash code of
056     *
057     * <pre>
058     * {@code
059     * Arrays.asList(entriesOnlyOnLeft(), entriesOnlyOnRight(),
060     *         entriesInCommon(), entriesDiffering())
061     * }
062     * </pre>
063     */
064    @Override
065    int hashCode();
066
067    /**
068     * A difference between the mappings from two maps with the same key. The {@link #leftValue} and
069     * {@link #rightValue} are not equal, and one but not both of them may be null.
070     *
071     * @param <V> identifying the type of the value
072     *
073     */
074    interface ValueDifference<V> {
075
076        /** @return the value from the left map (possibly null). */
077        V leftValue();
078
079        /** @return the value from the right map (possibly null). */
080        V rightValue();
081
082        /**
083         * Two instances are considered equal if their {@link #leftValue()} values are equal and
084         * their {@link #rightValue()} values are also equal.
085         */
086        @Override
087        boolean equals(Object other);
088
089        /**
090         * The hash code equals the value
091         * {@code Arrays.asList(leftValue(), rightValue()).hashCode()}.
092         */
093        @Override
094        int hashCode();
095    }
096}