// Copyright (c) 1998-2008 Adrian Kuhn <akuhn(a)students.unibe.ch>
//
// This file is part of ch.akuhn.util.
//
// ch.akuhn.util is free software: you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published by the
// Free Software Foundation, either version 3 of the License, or (at your
// option) any later version.
//
// ch.akuhn.util 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 Lesser General Public
// License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with ch.akuhn.util. If not, see <http://www.gnu.org/licenses/>.
//
package ch.akuhn.util;
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* A generic class for pairs.
*
*/
public class Pair<A,B> {
/**
* Iterate over all consecutive pairs of <tt>elements</tt>.
*
* @return if <tt>elements</tt> has less than two elements, the returned
* iterable is empty.
*/
public static final <E> Iterable<Pair<E,E>> cons(final Iterable<E> iterable) {
return new Iterable<Pair<E,E>>() {
public Iterator<Pair<E,E>> iterator() {
return new Iterator<Pair<E,E>>() {
private final Iterator<E> it = iterable.iterator();
private E prev = it.hasNext() ? it.next() : null;
public boolean hasNext() {
return it.hasNext();
}
public Pair<E,E> next() {
if (!hasNext()) throw new NoSuchElementException();
return Pair.of(prev, prev = it.next());
}
public void remove() {
throw new UnsupportedOperationException();
}
};
}
};
}
private static boolean equals(Object x, Object y) {
return (x == null && y == null) || (x != null && x.equals(y));
}
public static <A,B> Pair<A,B> of(A a, B b) {
return new Pair<A,B>(a, b);
}
public static final <A,B> Iterable<Pair<A,B>> zip(final Iterable<A> fst, final Iterable<B> snd) {
return new Iterable<Pair<A,B>>() {
public Iterator<Pair<A,B>> iterator() {
return new Iterator<Pair<A,B>>() {
private final Iterator<A> a = fst.iterator();
private final Iterator<B> b = snd.iterator();
public boolean hasNext() {
return a.hasNext() && b.hasNext();
}
public Pair<A,B> next() {
if (!hasNext()) throw new NoSuchElementException();
return Pair.of(a.next(), b.next());
}
public void remove() {
a.remove();
b.remove();
}
};
}
};
}
public final A fst;
public final B snd;
public Pair(A fst, B snd) {
this.fst = fst;
this.snd = snd;
}
@Override
public boolean equals(Object other) {
return other instanceof Pair<?,?> && equals(fst, ((Pair<?,?>) other).fst) && equals(snd, ((Pair<?,?>) other).snd);
}
@Override
public int hashCode() {
if (fst == null) return (snd == null) ? 0 : snd.hashCode() + 1;
else if (snd == null) return fst.hashCode() + 2;
else return fst.hashCode() * 17 + snd.hashCode();
}
@Override
public String toString() {
return "Pair[" + fst + "," + snd + "]";
}
}