5

JavaのListインターフェースのオブジェクトを、ミューテーションが不要になった時点で不変の同等物に変えると便利です。つまり、クライアントはfreezeリストを不変にするメソッドを呼び出すことができます。私にとっての直接の利点は、メモリを消費せずにスレッドセーフであるということです。深いコピー。(編集:すべてのスレッドで使用される1つの追加の不変コピーが手頃な価格であると想定すれば、人々は正しいでしょう。)

そのような機能を提供するサードパーティのインターフェイスまたはクラスはありますか?

4

4 に答える 4

6

Collections.unmodizableList(リストリスト)はどうですか?

于 2012-11-18T12:12:52.860 に答える
3

Guavaライブラリの一部としてImmutableListクラスがあります。このcopyOfメソッドを使用しImmutableListて、既存のからを作成できますIterable

List<String> immutableList = ImmutableList.copyOf(list);

于 2012-11-18T12:21:33.130 に答える
1

を使用してみてくださいCopyOnWriteArrayList

CopyOnWriteArrayListはクラスとほぼ同じように動作しますArrayListが、リストが変更されると、基になる配列を変更する代わりに、新しい配列が作成され、古い配列が破棄される点が異なります。これは、呼び出し元がイテレータ(つまり、copyOnWriteArrayListRef.iterator())を取得すると、基になるCopyOnWriteArrayListオブジェクトの配列への参照を内部的に保持することを意味します。これは不変であるため、リストの同期を必要とせずにトラバーサルに使用できます。copyOnWriteArrayListRefトラバーサルの前にcopyOnWriteArrayListRefリストをclone()し(つまり、同時変更のリスクがない)、パフォーマンスも向上します。

于 2012-11-18T12:13:00.593 に答える
1

クライアントが元の可変リストへの参照をまだ持っている場合は、を直接使用するだけでCollections.unmodifiableListは不十分です。

元の可変リスト(デリゲート)への内部参照を持つ委任リストの実装を作成し、すべてのメソッド呼び出しをそれに転送します。このようなコードを手作業で作成するのはPITAですが、たとえばEclipseは自動的にコードを生成できます。

次に、freezeメソッドを呼び出すときに、元のリストをでラップします。Collections.unmodifiableListこれにより、今後のすべてのメソッド呼び出しがFreezingList、変更不可能なビューを介してのみ元のデリゲートに移動するようになります。

より安全で柔軟性を低くするために、次のコンストラクターを変更して、元のリストをリストに渡す代わりに(元の可変リストへの参照をクライアントに残すことができます)、リストを内部でインスタンス化します(たとえば、ArrayList)。

public class FreezingList<E> implements List<E> {

    // the original list you delegate to (the delegate)
    private List<E> list;

    private boolean frozen = false;

    public FreezingList(List<E> list) {
        this.list = list;
    }

    public void freeze() {
        if (!frozen) {
            list = Collections.unmodifiableList(list);
            frozen = true;
        }
    }

    // all the delegating methods follow:
    public int size() {
        return list.size();
    }

    public E get(int index) {
        return list.get(index);
    }
    // etc. etc.
}
于 2012-11-18T13:02:09.947 に答える