2017-06-19 3 views
0

リストを入力として受け取るメソッドbrewMethod.getmMethodBrewPours()を作成しました。ユーザーの設定に応じて、メソッドはそれらの変数をそのまま、または数値で掛けて返します。返された値を新しい変数brewPoursとして保存します。問題は、このメソッドが新しい値を返すだけでなく、元の変数の値も変更していることです。なぜこれが変更されているのですか、それを防ぐために私は何をすべきですか?メソッドを呼び出す私のメソッドが私の元の変数の値を変更するのはなぜですか?

コード:メソッドの

// Custom class storing sets of data 
     brewMethod = i.getParcelableExtra("brew_method"); 

     //logs original packaged values 
     for (int j = 0; j < brewMethod.getmMethodBrewPours().size(); j++) { 
      Log.v("Original pour value #: " + j + ": ", brewMethod.getmMethodBrewPours() .get(j).toString()); 
     } 

     //changes values based on users preference 
     brewPours = replacePours(brewMethod.getmMethodBrewPours()); 

     //report the values again of the original packed values, but they are changed for some reason 
     for (int k = 0; k < brewMethod.getmMethodBrewPours().size(); k++) { 
      Log.v("New value on Original pour value #: " + k + ": ", brewMethod.getmMethodBrewPours() .get(k).toString()); 
     } 

     //log the values of the new variable brewPours 
     for (int l = 0; l < brewPours.size(); l++) { 
      Log.v("Value for new variable brewPours pour # " + l + ": ", brewPours.get(l).toString()); 
     } 

コード:

public List<Integer> replacePours(List<Integer> waterPours) { 

    SharedPreferences pref = getSharedPreferences("preferences", MODE_PRIVATE); 

    Integer newServingSize = pref.getInt("pref_key_serving_size", 1); 

    if (newServingSize == 2) { 
     for (int i = 0; i < waterPours.size(); i++) { 
      newPour = waterPours.get(i) * 2; 
      waterPours.set(i, newPour); 
     } 
    } 

    return waterPours; 
} 

出力:

06-19 16:50:34.474 30159-30159/com.brewguide.android.coffeebrewguide V/Original pour value #: 0:: 60 
06-19 16:50:34.474 30159-30159/com.brewguide.android.coffeebrewguide V/Original pour value #: 1:: 200 
06-19 16:50:34.474 30159-30159/com.brewguide.android.coffeebrewguide V/Original pour value #: 2:: 300 
06-19 16:50:34.474 30159-30159/com.brewguide.android.coffeebrewguide V/Original pour value #: 3:: 380 
06-19 16:50:34.475 30159-30159/com.brewguide.android.coffeebrewguide V/New value on Original pour value #: 0:: 120 
06-19 16:50:34.475 30159-30159/com.brewguide.android.coffeebrewguide V/New value on Original pour value #: 1:: 400 
06-19 16:50:34.475 30159-30159/com.brewguide.android.coffeebrewguide V/New value on Original pour value #: 2:: 600 
06-19 16:50:34.475 30159-30159/com.brewguide.android.coffeebrewguide V/New value on Original pour value #: 3:: 760 
06-19 16:50:34.475 30159-30159/com.brewguide.android.coffeebrewguide V/Value for new variable brewPours pour # 0:: 120 
06-19 16:50:34.475 30159-30159/com.brewguide.android.coffeebrewguide V/Value for new variable brewPours pour # 1:: 400 
06-19 16:50:34.475 30159-30159/com.brewguide.android.coffeebrewguide V/Value for new variable brewPours pour # 2:: 600 
06-19 16:50:34.475 30159-30159/com.brewguide.android.coffeebrewguide V/Value for new variable brewPours pour # 3:: 760 

編集: 私は、次のメソッドのコードを調整@Vampからのアドバイス私は探していた結果を得ました。以下は私の調整されたコードです、ありがとう!

public List<Integer> replacePours(List<Integer> waterPours) { 

    List<Integer> returnedPours = new ArrayList<>(); 
    SharedPreferences pref = getSharedPreferences("preferences", MODE_PRIVATE); 

    Integer newServingSize = pref.getInt("pref_key_serving_size", 1); 

    if (newServingSize == 2) { 
     for (int i = 0; i < waterPours.size(); i++) { 
      int newPour = waterPours.get(i) * 2; 
      returnedPours.add(newPour); 
     } 
    } 
    return returnedPours; 
} 
+1

このコードには「newPours」はありません。 –

+0

@OliverCharlesworthおかげで、私はちょうど質問を調整しました –

+0

それはコードがしているので、元の値を変更しています:あなたは 'waterPours'を反復していると同時に' waterPours.set(i、newPour ); '。 *変更したくない場合は、 'newPour'を新しいリストに追加してください。 'concurrentModificationException'を得るには、' get'と 'set'を使って、同じリストを反復して変更するときは注意してください。 – DarkCygnus

答えて

3

あなたはそれを修正するので、元のリストが変更されます。 Javaは値渡しですが、メソッドに与えている値は、オブジェクトではなくオブジェクトへの参照です。つまり、リストにメソッドを渡したり、リストを取得したりすることはありませんが、リストへの参照はメソッドに渡しています。参照先オブジェクトを変更すると、元のオブジェクトが変更されます。あなたのメソッドで新しいリストを作成し、そのリストを変更するのではなく、それを返さなければなりません。

+2

FWIW - https://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by-value –

1

参照による呼び出しと呼び出しによる呼び出しの違いを理解してください。

Javaでは、オブジェクトを渡すと、その関数への参照が渡されます。したがって、関数内のオブジェクトの変更は、関数外の変更を反映します。

あなたはこのラインで、元のオブジェクトの値を変更している、あなたの場合は

:あなたが関数内で新しいオブジェクトを作成し、それを変更した場合waterPours.set(i, newPour);

だから、それは良いでしょう。

public List<Integer> replacePours(List<Integer> waterPours) { 

    List<Integer> tempList = new ArrayList<Integer>(waterPours); 

    SharedPreferences pref = getSharedPreferences("preferences", MODE_PRIVATE); 

    Integer newServingSize = pref.getInt("pref_key_serving_size", 1); 

    if (newServingSize == 2) { 
     for (int i = 0; i < tempList.size(); i++) { 
      int newPour = tempList.get(i) * 2; 
      tempList.set(i, newPour); 
     } 
    } 

    return tempList; 
} 
+1

これは、実際にcall-by-refとcall-byの違いではありませんJavaが値渡しであることを考慮して、値。 –

+0

'newPour'の宣言がループ内の正しい場所に移動されていることがわかっているはずです。 –

+0

@LewBloch Done。しかし、私はOPが 'newPour'を宣言していないと思っていました。多分、グローバル変数です。 –

関連する問題