IT練習ノート

IT関連で調べたこと(実際は嵌ったこと)を書いています。

Javaコーディング規約に負けた話

実際はもっと諸々の条件や制約があり違うのですが、こんなことがやりたいことがありました。

  • リストがあって、その中の一連の部分のオブジェクトを、fromからtoで求めたい。
  • ここでいうfrom,toは、インデックスではなく、リストに含まれるオブジェクトで指定する。
  • 指定されたfrom,toのオブジェクトから対応するfromからtoのインデックスも求めたい。
  • Java8ではない。

例をあげると:

{"aaa", "bbb", "ccc", "ddd", "eee", "fff"}

があったとして、

from = "bbb"
to = "ddd"

を指定して、

{"bbb", "ccc", "ddd"} --- (a)

{1,2,3} --- (b)

を それぞれ求めることを考えます。

(a)を求めるには、やりかたはいろいろあると思いますが、例えば下記のような感じになるかと思います*1

    public <T> List<T> extract(List<T> src, T from, T to) {
        List<T> ret = new ArrayList<T>();
        boolean flg = false;
        for (int i = 0; i < src.size(); i++) {
            T t = src.get(i);
            if(!flg && from.equals(t)){
                flg = true;
            }
            if(flg){
                ret.add(src.get(i));// (***)
            }
            if(flg && to.equals(t)){
                flg = false;
            }
        }
        return ret;
    }

同じように(b)も(***)の部分をindexの値を設定するように変更した別のメソッドを作成すれば実装が出来ると思います。

ただ、(***)だけが異なって、ロジックの構造そのものは同じなので、共通化したいところです。

しばらく試行錯誤をしてみて、フラグを持たせてやって、

ret.add(idxFlg ? (T) Integer.valueOf(i) : src.get(i));

のようにすれば、ロジックが共通化できることが分かりました*2。 。

ただし、

Warning:java: 未チェックまたは安全ではありません。

と警告が出てしまいます。 @SuppressWarnings("unchecked")をつけてやれば、警告はなくなりますが、残念なことにそのときのプロジェクトのコーディング規約では@SuppressWarningsを使うのは禁止されていました。

もちろん、その前に、フラグをつかっている時点で野暮ったいので、実際は、下記のようにメソッドをラップして、意味の分かるメソッド名にするつもりでした。

    public <T> List<T> extractItems(List<T> src, T from, T to) {
        return extract(src, from, to, false);
    }

    public <T> List<Integer> extractIndexes(List<T> src, T from, T to) {
        return (List<Integer>)extract(src, from, to, true);
    }

    @SuppressWarnings("unchecked")
    private <T> List<T> extract(List<T> src, T from, T to, boolean idxFlg) {
       //実装
    }

SuppressWarningsを使っていても、publicにはしていないので、問題ないかと思いました。

が、コードレビューにて規約違反でNGとなってしまいました。

規約は規約として規約が大切なことは重々承知しているのですが、場合によっては守らなくても良いかと思うのですが、このような考えは認められませんでした。

*1:もっと賢いやり方があるのでしょうけど。。

*2:参考演算子(?)を使うことも禁止されていたのですが。。