All Downloads are FREE. Search and download functionalities are using the official Maven repository.

dk.clanie.collections.Tuple Maven / Gradle / Ivy

The newest version!
/**
 * Copyright (C) 2007, Claus Nielsen, [email protected]
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
package dk.clanie.collections;

/**
 * Tuple.
 * 
 * Provides static factory methods to instantiate Tuples of different sizes.
 * 

* Tuples can be used for ordering - for example as keys in collections. When * using Tuples for such purposes instantiate them like this: *

* Tuple myTuple = newTuple("one", 2, "three"); *

* This way you will not have access to individual elements of the Tuple. * If you need that you will have to use a more specific subclass like this: *

* Triple myTuple = newTuple("one", 2, "three"); *

* @author Claus Nielsen */ public abstract class Tuple implements Comparable { /** Tuple with one element. */ public static class Singleton extends Tuple { private T element; public Singleton(T element) { this.element = element; } public T get1st() { return element; } @SuppressWarnings("rawtypes") @Override public boolean equals(Object o) { if (o == null) return false; if (!(getClass() == o.getClass())) return false; return elementsEquals(element, ((Singleton) o).element); } @Override public int hashCode() { return element == null ? 0 : element.hashCode(); } @Override protected StringBuilder appendItems(StringBuilder builder) { return builder.append("[").append(element).append("]"); } @SuppressWarnings({ "unchecked", "rawtypes" }) @Override protected int compareItems(Tuple other) { if (!(other instanceof Singleton)) return 1; // Other is shorter return ((Comparable) element).compareTo(((Singleton) other).element); } } /** Tuple with two elements. */ public static class Pair extends Singleton { private T2 e2; public Pair(T1 e1, T2 e2) { super(e1); this.e2 = e2; } public T2 get2nd() { return e2; } @SuppressWarnings("rawtypes") @Override public boolean equals(Object o) { return super.equals(o) && elementsEquals(e2, ((Pair) o).e2); } @Override public int hashCode() { return super.hashCode() * 37 + (e2 == null ? 0 : e2.hashCode()); } @Override protected StringBuilder appendItems(StringBuilder builder) { return super.appendItems(builder).append("[").append(e2).append("]"); } @SuppressWarnings({ "unchecked", "rawtypes" }) @Override protected int compareItems(Tuple other) { int result = super.compareItems(other); if (result != 0) return result; if (!(other instanceof Pair)) return 1; // Other is shorter return ((Comparable) e2).compareTo(((Pair) other).e2); } } /** Tuple with three elements. */ public static class Triple extends Pair { private T3 e3; public Triple(T1 e1, T2 e2, T3 e3) { super(e1, e2); this.e3 = e3; } public T3 get3rd() { return e3; } @SuppressWarnings("rawtypes") @Override public boolean equals(Object o) { return super.equals(o) && elementsEquals(e3, ((Triple) o).e3); } @Override public int hashCode() { return super.hashCode() * 37 + (e3 == null ? 0 : e3.hashCode()); } @Override protected StringBuilder appendItems(StringBuilder builder) { return super.appendItems(builder).append("[").append(e3).append("]"); } @SuppressWarnings({ "unchecked", "rawtypes" }) @Override protected int compareItems(Tuple other) { int result = super.compareItems(other); if (result != 0) return result; if (!(other instanceof Triple)) return 1; // Other is shorter return ((Comparable) e3).compareTo(((Triple) other).e3); } } /** Tuple with four elements. */ public static class Quadruple extends Triple { private T4 e4; public Quadruple(T1 e1, T2 e2, T3 e3, T4 e4) { super(e1, e2, e3); this.e4 = e4; } public T4 get4th() { return e4; } @SuppressWarnings("rawtypes") @Override public boolean equals(Object o) { return super.equals(o) && elementsEquals(e4, ((Quadruple) o).e4); } @Override public int hashCode() { return super.hashCode() * 37 + (e4 == null ? 0 : e4.hashCode()); } @Override protected StringBuilder appendItems(StringBuilder builder) { return super.appendItems(builder).append("[").append(e4).append("]"); } @SuppressWarnings({ "unchecked", "rawtypes" }) @Override protected int compareItems(Tuple other) { int result = super.compareItems(other); if (result != 0) return result; if (!(other instanceof Quadruple)) return 1; // Other is shorter return ((Comparable) e4).compareTo(((Quadruple) other).e4); } } /** Tuple with five elements. */ public static class Quintuple extends Quadruple { private T5 e5; public Quintuple(T1 e1, T2 e2, T3 e3, T4 e4, T5 e5) { super(e1, e2, e3, e4); this.e5 = e5; } public T5 get5th() { return e5; } @SuppressWarnings("rawtypes") @Override public boolean equals(Object o) { return super.equals(o) && elementsEquals(e5, ((Quintuple) o).e5); } @Override public int hashCode() { return super.hashCode() * 37 + (e5 == null ? 0 : e5.hashCode()); } @Override protected StringBuilder appendItems(StringBuilder builder) { return super.appendItems(builder).append("[").append(e5).append("]"); } @SuppressWarnings({ "unchecked", "rawtypes" }) @Override protected int compareItems(Tuple other) { int result = super.compareItems(other); if (result != 0) return result; if (!(other instanceof Quintuple)) return 1; // Other is shorter return ((Comparable) e5).compareTo(((Quintuple) other).e5); } } /** Tuple with six elements. */ public static class Sextuple extends Quintuple { private T6 e6; public Sextuple(T1 e1, T2 e2, T3 e3, T4 e4, T5 e5, T6 e6) { super(e1, e2, e3, e4, e5); this.e6 = e6; } public T6 get6th() { return e6; } @SuppressWarnings("rawtypes") @Override public boolean equals(Object o) { return super.equals(o) && elementsEquals(e6, ((Sextuple) o).e6); } @Override public int hashCode() { return super.hashCode() * 37 + (e6 == null ? 0 : e6.hashCode()); } @Override protected StringBuilder appendItems(StringBuilder builder) { return super.appendItems(builder).append("[").append(e6).append("]"); } @SuppressWarnings({ "unchecked", "rawtypes" }) @Override protected int compareItems(Tuple other) { int result = super.compareItems(other); if (result != 0) return result; if (!(other instanceof Sextuple)) return 1; // Other is shorter return ((Comparable) e6).compareTo(((Sextuple) other).e6); } } /** * Returns a String representation of the Tuple. * * The whole Tuple is enclosed in square brackets, and so is * each element in it. * * Tuple.newTuple("one", 2).toString() will return "[[one][2]]". * * @see java.lang.Object#toString() */ @Override public String toString() { return appendItems(new StringBuilder("[")).append("]").toString(); } /** * toString helper. * * Each subclass should override this to call super.appendItems, * and the append "their own" item in square brackets. * * @param builder * @return StringBuilder */ protected abstract StringBuilder appendItems(StringBuilder builder); /** * Compares this Tuple with another Tuple for order. * * Tuples are compared by comparing each of their elements. * * Tuples with more elements are considered greater than Tuples with * fewer, but otherwise equal, elements. * * @see java.lang.Comparable#compareTo(java.lang.Object) * * @return A negative integer, zero or a positive integer as this Tuple is * less than, equal to or greater than the specified Tuple. * * @throws ClassCastException * if the items in this and the other Tuple aren't compatible, * if they don't implement {@link Comparable}. */ @Override public int compareTo(Tuple other) { int temp = compareItems(other); if (temp != 0) return temp; // All compared elements were equal. // If 'other' is of another class than 'this', it must have // more elements, and therefore it is considered greatest; // otherwise the tuples are equal. return getClass() == other.getClass() ? 0 : -1; } /** * compareTo() helper. *

* Subclasses should override this to call super.compareItems * and, if the result of that is zero, then compare "their own" item with * the corresponding item in the supplied Tuple. *

*/ protected abstract int compareItems(Tuple other); /** * Helper-method to check if two elements are equal. * * @param e1 * @param e2 * @return true if both e1 and e2 are null or if e1.equals(e2). */ protected static boolean elementsEquals(Object e1, Object e2) { return (e1 == null && e2 == null) || e1.equals(e2); } /** * Create new Singleton (Tuple with one element). * * @param * @param element * @return Singleton */ public static Singleton newTuple(T element) { return new Singleton(element); } /** * Create new Pair (Tuple with two elements). * * @param * @param * @param e1 * @param e2 * @return Pair */ public static Pair newTuple(T1 e1, T2 e2) { return new Pair(e1, e2); } /** * Create new Triple (Tuple with three elements). * * @param * @param * @param * @param e1 * @param e2 * @param e3 * @return Triple */ public static Triple newTuple(T1 e1, T2 e2, T3 e3) { return new Triple(e1, e2, e3); } /** * Create new Quadruple (Tuple with four elements). * * @param * @param * @param * @param * @param e1 * @param e2 * @param e3 * @param e4 * @return Quadruple */ public static Quadruple newTuple( T1 e1, T2 e2, T3 e3, T4 e4) { return new Quadruple(e1, e2, e3, e4); } /** * Create new Quintuple (Tuple with five elements). * * @param * @param * @param * @param * @param * @param e1 * @param e2 * @param e3 * @param e4 * @param e5 * @return Quintuple */ public static Quintuple newTuple( T1 e1, T2 e2, T3 e3, T4 e4, T5 e5) { return new Quintuple(e1, e2, e3, e4, e5); } /** * Create new Sextuple (Tuple with six elements). * * @param * @param * @param * @param * @param * @param * @param e1 * @param e2 * @param e3 * @param e4 * @param e5 * @param e6 * @return Sextuple */ public static Sextuple newTuple( T1 e1, T2 e2, T3 e3, T4 e4, T5 e5, T6 e6) { return new Sextuple(e1, e2, e3, e4, e5, e6); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy