質問

収集フィールドをgetterメソッドから返す前に変更できないようにすることがよくあります:

private List<X> _xs;
....
List<X> getXs(){
  return Collections.unmodifiableList(_xs);
}

しかし、上記のX自体がリストである場合、それを行う便利な方法は考えられません:

private List<List<Y>> _yLists;
.....
List<List<Y>> getYLists() {
  return Collections.unmodifiableList(_yLists);
}

上記の問題は、クライアントがリストのリストを変更できないにもかかわらず、埋め込みリストからYオブジェクトを追加/削除できることです。

何か考えはありますか

役に立ちましたか?

解決

私が思いつく最高の方法は、 Googleコレクションのフォワーディングリスト。コメントは大歓迎です。

private static <T> List<List<T>> unmodifiableList2(final List<List<T>> input) {
    return Collections.unmodifiableList(new ForwardingList<List<T>>() {
        @Override protected List<List<T>> delegate() {
            return Collections.unmodifiableList(input);
        }
        @Override public List<T> get(int index) {
            return Collections.unmodifiableList(delegate().get(index));
        }
    });
}

他のヒント

残念ながら、Javaで深いconst-nessを取得する簡単な方法はありません。リスト内のリストも変更不可能であることを常に確認することで、ハックする必要があります。

エレガントなソリューションを知りたいと思います。

clojureコレクション(マップ、セット、リスト、ベクター)はすべてネストでき、デフォルトでは不変です。純粋なJavaには、次のライブラリがあります。

http://code.google.com/p/pcollections/

>

Collections.unmodifiable *(...)メソッドの実装を見ると、それらが単にコレクションをラップしていることがわかります。同じ方法で深いユーティリティを実行することは実行可能でなければなりません。

これの欠点は、追加のメソッド呼び出しがコレクションアクセスに追加されるため、パフォーマンスに影響することです。

ここでの唯一の目標がカプセル化を強制することである場合、古典的な解決策はclone()などを使用してオブジェクトの内部状態ではない構造を返すことです。これは、すべてのオブジェクトを複製でき、コピーされた構造が十分に小さい場合にのみ機能することは明らかです。

これがかなり一般的に使用されるデータ構造である場合、別のオプションは、特定の呼び出しをより詳細に制御できるように、より具体的にアクセスするAPIを作成することです上記のように独自のリスト実装を作成することはこれを行うための 1 方法ですが、呼び出しを特定のユースケースに絞り込むことができる場合は、Listインターフェイスの代わりに特定のアクセスAPIを公開できます。

誰かがここに興味を持っている場合のために、簡単な解決策があります:

    public List<List<Double>> toUnmodifiable(List<List<Double>> nestedList) {
        List<List<Double>> listWithUnmodifiableLists = new ArrayList<>();
            for (List<Double> list : nestedList) {              
                listWithUnmodifiableLists
                    .add(Collections.unmodifiableList(list));
            }
        return Collections.unmodifiableList(listWithUnmodifiableLists);
    }

これは、たとえばgetList()メソッドでリストを公開する場合のソリューションとして使用できます。toUnmodifiable(mNestedList)、mNestedListはクラスのプライベートリストです。

AndroidでGSONを使用した解析に使用されるクラスを実装する場合、個人的にはこれが有用であることがわかりました。応答(この場合は逆シリアル化されたjson)を変更する意味がないため、このメソッドをゲッターでリストを公開し、リストが変更されないようにする方法。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top