2007 年 5 月 3 日 23 時 55 分

TreeSet と Comparator


このアーカイブは同期化されません。 mixi の日記が更新されても、このアーカイブには反映されません。


今日は、対照的な処理を実装するだけ。楽だ楽だ。

下への移動は、上への移動とほぼ同じ。
しかし順番が変わるので、並べ替えは降順にする必要がある。

TreeSet には NavigableSet を実装しているので、
#descendingIterator メソッドで逆順 Iterator が得られる。
しかし、このインタフェースは 1.6 で追加されたものだし、
これでは拡張 for 文が使えなくなってしまう。

そこで、TreeSet の並べ替え法則を逆にすることを考える。
順序付けは、Comparator を指定することで行われるので、
自然順序付けと逆になるような Comparator を作り、
TreeSet のコンストラクタに渡せば良いのだ。

では、下に移動を実装する。

========== ManageRulesAction#moveDown ==========
    public ActionForward moveDown(
            ActionMapping mapping, ActionForm form,
            HttpServletRequest request,
            HttpServletResponse response)
            throws Exception {

        // フォームを取得
        ManageFilterRulesForm manageForm =
                (ManageFilterRulesForm)form;

        // 選択されたルール番号を取得
        int[] selected = manageForm.getSelected();

        if (selected != null && selected.length > 0) {

            // 降順に並べる Comparator を作る
            Comparator<Integer> comparator =
                    new Comparator<Integer>() {
                        public int compare(Integer o1,
                                Integer o2) {
                            return o2.compareTo(o1);
                        }
                    };

            // 重複を省き、かつ降順に並べる
            SortedSet<Integer> indexes =
                    new TreeSet<Integer>(comparator);
            for (int index : selected) {
                indexes.add(index); // ボックス化
            }

            // 現在のフィルタ設定を読み込む
            Filter filter = FilterManager.load();

            List<FilterRule> rules = filter.getRules();

            // 最後のルールが選択されていたら動かせない
            if (indexes.first() < rules.size() - 1) {

                // 後ろから順に下と交換
                for (int index : indexes) {
                    FilterRule rule = rules.get(index);
                    rules.set(index, rules
                            .get(index + 1));
                    rules.set(index + 1, rule);
                }

                // 保存する
                FilterManager.save(filter);

            }

        }

        // OK
        return mapping
                .findForward(Forwards.SUCCESS_KEY);

    }
========== end of ManageRulesAction#moveDown ==========

Set に入っている値は、ボックス化された Integer だ、
なので、Integer 用の逆順 Comparator を作る。

Integer は Comparable なので、
インスタンスが持つ compareTo メソッドを使えば楽だ。
元々プリミティブ値をボックス化した Integer なので、
このメソッドに null 引数はあり得ない。

この comparator を TreeSet に渡せば、
自動的に逆順に整列されるようになる。
そのため、indexes.first() で得られる値は、
選択された中で最も大きい番号になるのである。

後は下の要素と入れ替える処理を繰り返して完了となる。



Copyright (c) 1994-2007 Project Loafer. All rights reserved.