/* * @(#) ConstPair.java - Class for immutable pairs of objects. * (c) 2000 Ivan Maidanski http://ivmai.chat.ru * Freeware class library sources. All rights reserved. ** * Language: Java [pure] * Tested with: JDK v1.1.6 * Last modified: 2000-12-31 15:30:00 GMT+03:00 */ /* * This software is the proprietary information of the author. ** * Permission to use, copy, and distribute this software and its * documentation for non-commercial purposes and without fee is * hereby granted provided that this copyright notice appears in all * copies. ** * This software should not be modified in any way; any found bug * should be reported to the author. ** * The author disclaims all warranties with regard to this software, * including all implied warranties of merchantability and fitness. * In no event shall the author be liable for any special, indirect * or consequential damages or any damages whatsoever resulting from * loss of use, data or profits, whether in an action of contract, * negligence or other tortuous action, arising out of or in * connection with the use or performance of this software. */ package ivmai.util; import java.io.Serializable; /** * Class for immutable pairs of objects. ** * This instantable class is useful for representation of a constant * sortable pair of custom objects of any type (a container for two * elements). ** * @see ConstVector * @see GComparator ** * @version 2.0 * @author Ivan Maidanski ** * @since 1.2 */ public final class ConstPair implements Immutable, ReallyCloneable, Serializable, Indexable, Sortable { /** * The class version unique identifier for serialization * interoperability. ** * @since 1.8 */ private static final long serialVersionUID = 3724364892682440569L; /** * The first custom object of this pair. ** * @serial ** * @see ConstPair#ConstPair(java.lang.Object, java.lang.Object) * @see #getAt(int) */ protected final Object valueA; /** * The second custom object of this pair. ** * @serial ** * @see ConstPair#ConstPair(java.lang.Object, java.lang.Object) * @see #getAt(int) */ protected final Object valueB; /** * Constructs an immutable 'pair' container. ** * @param valueA * the first custom object (may be null). * @param valueB * the second custom object (may be null). ** * @see #getAt(int) * @see #equals(java.lang.Object) * @see #greaterThan(java.lang.Object) * @see #toString() */ public ConstPair(Object valueA, Object valueB) { this.valueA = valueA; this.valueB = valueB; } /** * Returns the number of elements in this container. ** * Here, the result is 2. ** * @return * amount (non-negative value) of elements. ** * @see #getAt(int) */ public int length() { return 2; } /** * Returns value of the element at the specified index. ** * @param index * the index (must be in the range) at which to return an element. * @return * an element (may be null) at index. * @exception ArrayIndexOutOfBoundsException * if index is negative or is not less than * length(). ** * @see ConstPair#ConstPair(java.lang.Object, java.lang.Object) * @see #length() */ public Object getAt(int index) throws ArrayIndexOutOfBoundsException { if (index >> 1 != 0) throw new ArrayIndexOutOfBoundsException(index); Object value = this.valueA; if (index > 0) value = this.valueB; return value; } /** * Creates and returns a copy of this object. ** * The result is the same as of * new ConstPair(getAt(0), getAt(1)). ** * @return * a copy (not null and != this) of * this instance. * @exception OutOfMemoryError * if there is not enough memory. ** * @see ConstPair#ConstPair(java.lang.Object, java.lang.Object) * @see #getAt(int) * @see #equals(java.lang.Object) */ public Object clone() { Object obj; try { if ((obj = super.clone()) instanceof ConstPair && obj != this) return obj; } catch (CloneNotSupportedException e) {} throw new InternalError("CloneNotSupportedException"); } /** * Computes and returns a hash code value for the object. ** * This method hashes all non-null elements of * this container and mixes them all to produce a * single hash code value. ** * @return * a hash code value for this object. ** * @see #length() * @see #getAt(int) * @see #equals(java.lang.Object) */ public int hashCode() { int code = 0; Object value; if ((value = this.valueA) != null) { code = value.hashCode(); code = (code << 5) - code; } if ((value = this.valueB) != null) code ^= value.hashCode(); return ((code << 5) - code) ^ 2; } /** * Indicates whether this object is equal to the * specified one. ** * This method returns true if and only if * obj is instance of this container class and all * elements of this container are equal to the * corresponding elements of obj. ** * @param obj * the object (may be null) with which to compare. * @return * true if and only if this value is the * same as obj value. ** * @see ConstPair#ConstPair(java.lang.Object, java.lang.Object) * @see #length() * @see #getAt(int) * @see #hashCode() * @see #greaterThan(java.lang.Object) */ public boolean equals(Object obj) { boolean isEqual = true; if (obj != this) { isEqual = false; if (obj instanceof ConstPair) { Object value; ConstPair pair = (ConstPair)obj; if ((value = this.valueA) != null && value.equals(pair.valueA) || value == null && pair.valueA == null) if ((value = this.valueB) != null) isEqual = value.equals(pair.valueB); else if (pair.valueB == null) isEqual = true; } } return isEqual; } /** * Tests for being semantically greater than the argument. ** * The result is true if and only if obj is * instance of this class and this object * is greater than the specified object. Containers are compared in * the element-by-element manner, starting at index 0. * So, the first elements pair is tested for equality and then it * (if equality test has failed) or (else) the second elements pair * is compared through INSTANCE of * GComparator class (and the result of this comparison * is returned). ** * @param obj * the second compared object (may be null). * @return * true if obj is comparable with * this and this object is greater than * obj, else false. ** * @see #length() * @see #getAt(int) * @see #equals(java.lang.Object) ** * @since 1.8 */ public boolean greaterThan(Object obj) { if (obj == this || !(obj instanceof ConstPair)) return false; ConstPair pair = (ConstPair)obj; Object value, pairValue = pair.valueA; if ((value = this.valueA) != null && value.equals(pairValue) || value == null && pairValue == null) { value = this.valueB; pairValue = pair.valueB; } return GComparator.INSTANCE.greater(value, pairValue); } /** * Converts container to its 'in-line' string representation. ** * Here, these two values are placed into the resulting string in * the direct index order, delimited by a single space. ** * @return * the string representation (not null, with non-zero * length()) of this object. * @exception OutOfMemoryError * if there is not enough memory. ** * @see ConstPair#ConstPair(java.lang.Object, java.lang.Object) * @see #length() * @see #getAt(int) */ public String toString() { Object value; return new String((new StringBuffer(24)). append((value = this.valueA) != null ? value.toString() : "null").append(' '). append((value = this.valueB) != null ? value.toString() : "null")); } }