2017-06-19 58 views
0

我已經創建了一個方法,它將一個List作爲輸入,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'。迭代和修改同一個列表時也要小心,因爲你可以通過'get'和'set'來獲得一個'ConcurrentModificationException' – 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

這實際上並不是真正意義上的通過撥號和呼叫之間的區別值,因爲Java是按值調用的。 –

+0

你應該已經顯示'newPour'的聲明移到了循環內的正確位置。 –

+0

@LewBloch完成。雖然,我認爲OP沒有聲明'newPour',所以也許它是一些全局變量。 –

相關問題