package com.github.liblevenshtein.collection; import java.io.Serializable; import org.apache.commons.lang3.builder.HashCodeBuilder; import lombok.NonNull; import lombok.Value; /** * Symmetric, immutable pairs are equivalent if they contain equivalent * elements, regardless the order of the elements. * @param <Type> Kind of the elements stored in this pair. * @author Dylon Edwards * @since 2.1.0 */ @Value public class SymmetricImmutablePair<Type extends Comparable<Type>> implements Comparable<SymmetricImmutablePair<Type>>, Serializable { private static final long serialVersionUID = 1L; /** * First element of this pair. */ private final Type first; /** * Second element of this pair. */ private final Type second; /** * Returned from {@link #hashCode()}. */ private final int hashCode; /** * Constructs a new symmetric, immutable pair on the given parameters. The * hashCode is determined upon construction, so the assumption is made that * first and second are immutable or will not be mutated. If they or any of * their hashable components are mutated post-construction, the hashCode will * be incorrect and the behavior of instances of this pair in such structures * as hash maps will be undefined (e.g. this pair may seem to "disappear" from * the hash map, even though it's still there). * @param first First element of this pair * @param second Second element of this pair */ public SymmetricImmutablePair( @NonNull final Type first, @NonNull final Type second) { if (first.compareTo(second) < 0) { this.first = first; this.second = second; } else { this.first = second; this.second = first; } this.hashCode = new HashCodeBuilder(541, 7873) .append(this.first) .append(this.second) .toHashCode(); } /** * {@inheritDoc} */ @Override public int compareTo(final SymmetricImmutablePair<Type> other) { final int c = first.compareTo(other.first()); if (0 == c) { return second.compareTo(other.second()); } return c; } /** * {@inheritDoc} */ @Override public boolean equals(final Object o) { if (!(o instanceof SymmetricImmutablePair)) { return false; } @SuppressWarnings("unchecked") final SymmetricImmutablePair<Type> other = (SymmetricImmutablePair<Type>) o; return 0 == compareTo(other); } /** * {@inheritDoc} */ @Override public int hashCode() { return hashCode; } }