LoginSignup
5

More than 5 years have passed since last update.

[Javaの小枝] AutoCloseable な Tuple を作る

Posted at

概要

前回説明した 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();}
    }
}

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5