概要
前回説明した Tuple の AutoClosable 版を作成する
実装
以下に実装を示す。何故こんなものを作成するのか、今回は説明しない。次回、詳細を説明するので、それまで待っていて欲しい。クラス名は TupleAutoCloseable で TupleAC とした。TupleACは自身の close( ) が呼びだされた際、保持しているオブジェクトが AutoCloseable インターフェースを持っている時だけ保持しているオブジェクトの close を実行する。
このクラスの要点はいくつかあるが
- closeの順序は後ろの引数から。 Tuple3AC<A, B, C>(A a, B b, C c) であれば c から先に行なう。
- 妖しいコンストラクタが一つ追加されている。要注目。
- get( ) メソッドは常に最後の要素が取得できる。Tuple3AC<A, B, C>(A a, B b, C c)であれば c が取得できる。
何故このようなクラスを定義するのか次回説明する。
TupleUtils.java
public class TupleUtils {
private static class PairAC<A,B> extends Pair<A, B> implements AutoCloseable {
public PairAC(A car_, B cdr_) {super(car_, cdr_);}
@Override public void close() throws Exception {
Exception thCdr = execAutoClose(cdr);
Exception thCar = execAutoClose(car);
if (thCdr != null) throw thCdr;
if (thCar != null) throw thCar;
}
private static Exception execAutoClose(Object o) {
try {
if (o != null && o instanceof AutoCloseable) ((AutoCloseable) o).close();
return null;
} catch (Exception e) {return e;}
}
}
public static class Tuple1AC<A> extends PairAC<A, Object> {
public Tuple1AC(A a) {super(a, null);}
public Tuple1AC(Supplier<A> a) {super(a.get(), null);}
public A get() {return car;}
}
public static class Tuple2AC<A, B> extends PairAC<A, Tuple1AC<B>> {
public Tuple2AC(A a, B b) {super(a, new Tuple1AC<>(b));}
public Tuple2AC(A a, Function<A, B> b) {super(a, new Tuple1AC<>(b.apply(a)));}
public B get() {return cdr.get();}
}
public static class Tuple3AC<A, B, C> extends PairAC<A, Tuple2AC<B, C>> {
public Tuple3AC(A a, B b, C c) {super(a, new Tuple2AC<>(b, c));}
public Tuple3AC(A a, Function<A, B> b, Function<B, C> c) {super(a, new Tuple2AC<>(b.apply(a), c));}
public C get() {return cdr.get();}
}
public static class Tuple4AC<A, B, C, D> extends PairAC<A, Tuple3AC<B, C, D>> {
public Tuple4AC(A a, B b, C c, D d) {super(a, new Tuple3AC<>(b, c, d));}
public Tuple4AC(A a, Function<A, B> b, Function<B, C> c, Function<C, D> d) {super(a, new Tuple3AC<>(b.apply(a), c, d));}
public D get() {return cdr.get();}
}
public static class Tuple5AC<A, B, C, D, E> extends PairAC<A, Tuple4AC<B, C, D, E>> {
public Tuple5AC(A a, B b, C c, D d, E e) {super(a, new Tuple4AC<>(b, c, d, e));}
public Tuple5AC(A a, Function<A, B> b, Function<B, C> c, Function<C, D> d, Function<D, E> e) {super(a, new Tuple4AC<>(b.apply(a), c, d, e));}
public E get() {return cdr.get();}
}
}