2

jsf Webサーバーのリストを使用して、たとえばWebページからデータモデルにアクセスしています。これらのリストへのアクセスは、他のさまざまな場所(Webサービス、ツール)からも行われます。

私が返したリストを頼りにしている誰かによって壊れたコードがあります。私が開発者チームの誰かについて話しているのは、このコードを使用しているのは私たちだけです。私はこの関数についておよそ300の参照を持っており、修正をうまく行うことはパフォーマンスに関連している可能性があります。

リストは1〜10000のエントリで、通常は10〜100のリストがあります。実際には、おそらく20のリストがあり、それぞれに8つのエントリがあるので、それほど大したことではありません。しかし、私はもっと時々持つことができます

私はところでこのような関数について話している:

public List<MyObject> getMyObjectList() {
    if (this.myObjects== null) {
        myObjects = new ArrayList<MyObject>(myObjectsMap.values());
    }
    return myObjects;
}

今、私はもちろんこのように戻ることができます:

    public List<MyObject> getMyObjectList() {
        if (this.myObjects== null) {
            myObjects = new ArrayList<MyObject>(myObjectsMap.values());
        }
        return Collections.unmodifiableList(myObjects );
}

しかし、これは最終的にはさまざまなプロジェクト/アプリケーションのいくつかの場所で機能しなくなります。変更不可能なものを返し、javadocを追加し、壊れたものをすべて修正するのが最もクリーンです。しかし:-Dこれは仕事です。おそらく、およそ10個のアプリケーションをテストする必要があります。

一方、私は新しいリストを返すことができます、例えば

public List<MyObject> getMyObjectList() {
    return new ArrayList<MyObject>(myObjectsMap.values());
}

これはほとんど作業ではありませんが、これに関するパフォーマンスの問題はどうですか?それ以外は、誰かが私が返したリストから何かを削除している場合、それは黙ってアプリケーションを壊します。

だから:パフォーマンスの問題は何ですか?それは問題ですか?

あなたならどうしますか?

4

2 に答える 2

2

あなたならどうしますか?

私があなたを正しく理解しているなら、これはいくつかのアプリケーションで使用される本番ライブラリです。そして、好むと好まざるとにかかわらず、の事実上の契約getMyObjectList()は、ユーザーがエラーや例外を取得することなくリストをソートできることです。

私はすぐにこのメソッドを変更し、防御コピーを返します。

// good idea
public List<MyObject> getMyObjectList() {
    return new ArrayList<MyObject>(myObjectsMap.values());
}

これで、誰かが内部コレクションをソートしていて、契約を破っていないという問題が修正されました。実際、Javadocを更新して、コピーを使用して好きなことを実行できることをユーザーに伝えることもできます。

これにより、パフォーマンスの問題が発生する場合と発生しない場合があります。コレクション内のオブジェクトはコピーされていないことを忘れないでください-それらはまだ共有されています。新しい配列リストと、オブジェクトを追跡するために必要な内部オブジェクトを作成しているだけです。

これらのコピーがパフォーマンスの問題を引き起こしていることが判明した場合は、内部コレクションの読み取り専用キャッシュを含めるようにクラスを拡張することを検討できます。これにアクセスするには、メソッドに新しい名前(ex getMySharedObjectList)を付ける必要があります。パフォーマンスのニーズに応じて、この新しいメソッドを使用するようにクライアントコードを徐々に更新できます。

しかし、このようにしないでください。この方法は特に悪いと思います。

// bad idea
public List<MyObject> getMyObjectList() {
    if (this.myObjects== null) {
        myObjects = new ArrayList<MyObject>(myObjectsMap.values());
    }
    return Collections.unmodifiableList(myObjects );
}

myObjectsがmyObjectsMapと同期しなくなるのが非常に簡単な状況を作成しました。(getMyObjectListを呼び出した後にアイテムがmyObjectsMapに追加されるとどうなりますか?)同時に、誰かがメソッドを呼び出すたびにリストのコピーを作成します。つまり、そもそも理論上のパフォーマンスの向上をあきらめただけです。

とにかく、頑張ってください。お役に立てれば。

于 2012-10-29T14:38:19.477 に答える
0

アプリケーションをテストする余裕があれば、unmodizableListを使用します。これにより、将来、他の関連する問題からあなたを救うことができます。

于 2012-10-29T14:08:07.453 に答える