オブジェクト指向の設計パラダイム内では、オブジェクト自体の外側のオブジェクトを変更することはできません。オブジェクトの状態に対する変更は、オブジェクトのメソッドを介して行う必要があります。
したがって、void predictPrice(Item item)
他のクラスのメンバー関数は間違っています。Cの時代には受け入れられたかもしれませんが、JavaとC ++の場合、オブジェクトの変更はオブジェクトへのより深い結合を意味し、他の設計上の問題につながる可能性があります(クラスをリファクタリングしてそのフィールドを変更すると、 「predictPrice」を他のファイルで変更する必要があります。
新しいオブジェクトを返しますが、関連する副作用はありません。渡されたパラメーターは変更されません。あなた(predictPriceメソッド)は、そのパラメーターが他にどこで使用されているかを知りません。Item
ハッシュのキーはどこかにありますか?これでハッシュコードを変更しましたか?他の誰かが、それが変わらないことを期待していますか?
これらの設計上の問題は、オブジェクトを変更してはならないことを強く示唆するものです(多くの場合、不変性を主張します)。そうする場合、状態への変更は何かではなくオブジェクト自体によって含まれ、制御されるべきですそれ以外の場合はクラス外。
ハッシュ内の何かのフィールドをいじるとどうなるか見てみましょう。いくつかのコードを見てみましょう:
import java.util.*;
public class Main {
public static void main (String[] args) {
Set set = new HashSet();
Data d = new Data(1,"foo");
set.add(d);
set.add(new Data(2,"bar"));
System.out.println(set.contains(d));
d.field1 = 2;
System.out.println(set.contains(d));
}
public static class Data {
int field1;
String field2;
Data(int f1, String f2) {
field1 = f1;
field2 = f2;
}
public int hashCode() {
return field2.hashCode() + field1;
}
public boolean equals(Object o) {
if(!(o instanceof Data)) return false;
Data od = (Data)o;
return od.field1 == this.field1 && od.field2.equals(this.field2);
}
}
}
イデオン
そして、これは最大のコードではないことを認めます(フィールドに直接アクセスします)が、HashMapのキーとして使用される可変データ、またはこの場合は単にハッシュセット。
このコードの出力は次のとおりです。
true
false
何が起こったのかは、挿入されたときに使用されたhashCodeがオブジェクトがハッシュ内にあるということです。hashCodeの計算に使用される値を変更しても、ハッシュ自体は再計算されません。これは、パッティングの危険性である任意のハッシュのキーとして変更可能なオブジェクトを。
したがって、質問の元の側面に戻ると、呼び出されているメソッドは、パラメーターとして取得しているオブジェクトがどのように使用されているかを「知りません」。提供でクリープすることができます微妙なバグの数があることを、この手段を行うための唯一の方法として「のmutateオブジェクトをすることができます」。同様に、ハッシュの値を失う...あなたはより多くの追加とハッシュが再ハッシュ取得しない限り-信頼を私に、追い詰めるのは厄介なバグです(hashMapにさらに20個の項目を追加すると、突然値が表示されるまで値を失いました)。
- オブジェクトを変更する非常に正当な理由がない限り、新しいオブジェクトを返すことが最も安全です。
- 存在するときであるオブジェクトを変更する正当な理由は、その変更は、オブジェクト自体(メソッドを呼び出す)ことによってではなく、そのフィールドをひねりができ、いくつかの外部関数を介して行われるべきです。
- これにより、オブジェクトをより低いメンテナンスコストでリファクタリングできます。
- これにより、オブジェクトは、ハッシュコードを計算する値が変更されないことを確認できます(または、ハッシュコード計算の一部ではありません)
関連:同じifステートメント内で、ifステートメントの条件として使用される引数の値を上書きして返す