2017-01-11 11 views
2

私は次のクラスのようなオブジェクトのリストを持っている:更新パラメータ:戻りリストやない

class A { 
    private String property1; 
    private String property2; 
    //Setters && Getters 

} 

ので、いくつかの操作をした後、私はデフォルト値でリストを更新する必要があります次のようないくつかのロジック:

listOfA.forEach(item -> { 
     item.setProperty1(findSomething()); 
} 

このロジックは数回繰り返されますので、メソッドにエクスポートすることを検討しています。したがって、私の質問はこのメソッドに関連しています:リストのコピー参照をvoidメソッドで更新するか、返すか、新しいリストを作成して更新する必要がありますか?

オプション1:リストのコピー参照を更新します

private void updateList(List<A> listOfA) { 
    listOfA.forEach(item -> { 
     item.setProperty1(findSomething()); 
    } 
} 

オプション2:、他から新しいリストを作成し、これを更新し、それを返す:それ

private List<A> updateList(List<A> listOfA) { 
    listOfA.forEach(item -> { 
     item.setProperty1(findSomething()); 
    } 

    return listOfA; 
} 

オプション3戻ります

private List<A> updateList(List<A> listOfA) { 
    List<A> newList = new ArrayList<>(); 
    //Logic to copy listOfA in newList.... 

    newList.forEach(item -> { 
     item.setProperty1(findSomething()); 
    } 

    return newList ; 
} 
+0

あなたが言及したすべてのオプションがafterallと同じ結果を与えるので、たぶんユースケースを明確にするかもしれません。オプション3)新しいリストの作成では、私はJavaの変更可能なリストでは使用しません。 – unserializable

+0

ユースケースによっては、[Observer pattern](https://en.wikipedia.org/wiki/Observer_pattern)を実装し、その状態を 'findSomething()'で更新する項目Aであっても、 Aにとって重要な一定の状態が変更されました。 – unserializable

答えて

2

最終的にあなたが好むオプションは非常に個人的な意見です。ただし、決定プロセスで役立ついくつかの考慮事項があります。

第1と第2のオプションは事実上同じです。両方ともパラメータとして渡されるListで動作します。リストを更新しても新しいものは作成されません。署名のみ(追加のドキュメントなし)オプション2は、返されたリストが新しいListインスタンスであることを示している可能性があるため、これは選択肢1として選択肢を示唆しています。

オプション2と3のようにListを返すと、そのリストで操作を実行して変更可能にするという利点があります。

最後のオプションは、防御コピーを使用して、入力Listの新しいインスタンスを実際に作成し、そのリストで操作します。そうするのがよい習慣ですが、望ましくないかもしれないいくつかの副作用を持つことがあります。オプション2では、パラメータとして渡されたのと同じインスタンスであるため、返されたリストが何かに割り当てられる必要はありません。これは、オプション3の場合ではありません。ここで結果を割り当てる必要があります。そうでなければ、ガベージコレクションの対象となります。

0

方法:3

uはそれがヒープ内の特定のメモリを必要とする新しいリストオブジェクトを作成するrを。そして、あなたはあなたの楽器リストからコンテンツをコピーし、それを更新して新しいリストを返します。ここで新しいリストオブジェクトを作成すると、頭痛が増します。それの必要はありません。

方法:あなたは同じリストを返すBT全く新しいリストが作成されません。この方法では2

。 javaは値による呼び出しで機能します(ここでの値はrefオブジェクトの値を意味します)。呼び出したメソッドの更新リストを返す必要はありません。その間、オブジェクトを保持している間にそのメソッドのメタデータを増やします。

方法:1

これは最善の方法です。ここでは、値による呼び出しの利点を使用しています(ここでの値は、refオブジェクトの値を意味します)。不要な余分なメモリが占​​有されることはありません。 不要な返品はありません。それは右のapprochです。

0

すべては状況によって異なります。

オプション1 このケースは、他の場所であなたのリストを使用する必要がない場合に適しています。つまり、他のオブジェクトがこのリスト参照をメンバとして持つ場合、このオブジェクトはこのメンバも変更されます。

オプション2 このケースはケース1のようであり、この方法をケース1として使用できますが、ここではリストを返すことができます。これは、最初のケースでは、いくつかの利点をもたらし、あなたはストリームAPIまたはOptionalsのチェーンにあなたの方法を使用することができます。

private List<A> updateList(List<A> listOfA) { 
    List<A> newList = new ArrayList<>(); 
    //Logic to copy listOfA in newList.... 

    newList.forEach(item -> item.setProperty1(findSomething())); 

    return newList ; 
} 

public List<A> myMethod() { 
    List<A> myList = null; 
    // possible initialization of list 
    // ... 
    // here we update list. In the case when list is null then we do not modify it 
    return Optional.ofNullable(myList).map(this::updateList).orElse(null); 
} 

オプション3 あなたが別のものに配列をコピーするこの場合。初期の配列を変更すべきでない場合、例えば他のクラスのフィールドである場合などに意味があります。

関連する問題