/* * This software is subject to the terms of the Eclipse Public License v1.0 * Agreement, available at the following URL: * http://www.eclipse.org/legal/epl-v10.html. * You must accept the terms of that agreement to use this software. * * Copyright (c) 2002-2013 Pentaho Corporation.. All rights reserved. */ package mondrian.util; import mondrian.olap.Util; import java.util.Iterator; /** * Tuple of three values. * * <p>Because a triple implements {@link #equals(Object)}, {@link #hashCode()} * and {@link #compareTo(mondrian.util.Triple)}, it can be used in any kind of * {@link java.util.Collection}. * * @author jhyde */ public class Triple<T0, T1, T2> implements Comparable<Triple<T0, T1, T2>> { public T0 v0; public T1 v1; public T2 v2; /** * Creates a Triple. * * @param v0 Value #0 * @param v1 Value #1 * @param v2 Value #2 */ public Triple(T0 v0, T1 v1, T2 v2) { this.v0 = v0; this.v1 = v1; this.v2 = v2; } /** * Creates a Triple. * * @param v0 Value #0 * @param v1 Value #1 * @param v2 Value #2 * @return a new Triple */ public static <T0, T1, T2> Triple<T0, T1, T2> of(T0 v0, T1 v1, T2 v2) { return new Triple<T0, T1, T2>(v0, v1, v2); } public boolean equals(Object obj) { if (obj instanceof Triple) { //noinspection unchecked Triple<T0, T1, T2> pair = (Triple) obj; return Util.equals(this.v0, pair.v0) && Util.equals(this.v1, pair.v1) && Util.equals(this.v2, pair.v2); } return false; } public int hashCode() { int k0 = (v0 == null) ? 0 : v0.hashCode(); int k1 = (v1 == null) ? 0 : v1.hashCode(); int k2 = (v2 == null) ? 0 : v2.hashCode(); return ((k0 << 8) | k0) ^ (k1 << 4 | k1) ^ k2; } public int compareTo(Triple<T0, T1, T2> that) { int c = compare((Comparable) this.v0, (Comparable)that.v0); if (c == 0) { c = compare((Comparable) this.v1, (Comparable)that.v1); } if (c == 0) { c = compare((Comparable) this.v2, (Comparable)that.v2); } return c; } public String toString() { return "<" + v0 + ", " + v1 + ", " + v2 + ">"; } /** * Compares a pair of comparable values of the same type. Null collates * less than everything else, but equal to itself. * * @param c1 First value * @param c2 Second value * @return a negative integer, zero, or a positive integer if c1 * is less than, equal to, or greater than c2. */ private static <C extends Comparable<C>> int compare(C c1, C c2) { if (c1 == null) { if (c2 == null) { return 0; } else { return -1; } } else if (c2 == null) { return 1; } else { return c1.compareTo(c2); } } /** * Returns an iterable over the slice #0 of an iterable. * * @param iterable Iterable over triples * @param <T0> Type #0 * @param <T1> Type #1 * @param <T2> Type #2 * @return Iterable over the 0'th elements of each triple */ public static <T0, T1, T2> Iterable<T0> iter0( final Iterable<Triple<T0, T1, T2>> iterable) { return new Iterable<T0>() { public Iterator<T0> iterator() { final Iterator<Triple<T0, T1, T2>> iterator = iterable.iterator(); return new Iterator<T0>() { public boolean hasNext() { return iterator.hasNext(); } public T0 next() { return iterator.next().v0; } public void remove() { iterator.remove(); } }; } }; } /** * Returns an iterable over the slice #1 of an iterable. * * @param iterable Iterable over triples * @param <T0> Type #0 * @param <T1> Type #1 * @param <T2> Type #2 * @return Iterable over the 1'th elements of each triple */ public static <T0, T1, T2> Iterable<T1> iter1( final Iterable<Triple<T0, T1, T2>> iterable) { return new Iterable<T1>() { public Iterator<T1> iterator() { final Iterator<Triple<T0, T1, T2>> iterator = iterable.iterator(); return new Iterator<T1>() { public boolean hasNext() { return iterator.hasNext(); } public T1 next() { return iterator.next().v1; } public void remove() { iterator.remove(); } }; } }; } /** * Returns an iterable over the slice #2 of an iterable. * * @param iterable Iterable over triples * @param <T0> Type #0 * @param <T1> Type #1 * @param <T2> Type #2 * @return Iterable over the 2'th elements of each triple */ public static <T0, T1, T2> Iterable<T2> iter2( final Iterable<Triple<T0, T1, T2>> iterable) { return new Iterable<T2>() { public Iterator<T2> iterator() { final Iterator<Triple<T0, T1, T2>> iterator = iterable.iterator(); return new Iterator<T2>() { public boolean hasNext() { return iterator.hasNext(); } public T2 next() { return iterator.next().v2; } public void remove() { iterator.remove(); } }; } }; } } // End Triple.java