[英]Passing References to Methods Java
我一直在嘗試解決需要兩種方法的問題:
它看起來很像,但您實際上並不需要閱讀這些方法。 只是知道我正在將int[][]
傳遞給方法,更改方法內部的int[][]
,然后檢查方法外部與int[][]
相等性。
public static boolean One(int[][] matrix){
matrix = transpose(matrix);
matrix = reverseRow(matrix);
return Arrays.deepEquals(matrix, changed);
}
public static boolean Two(int[][] matrix){
//180 degree clockwise
matrix = transpose(matrix);
matrix = reverseRow(matrix);
matrix = transpose(matrix);
matrix = reverseRow(matrix);
return Arrays.deepEquals(matrix,changed);
}
public static int[][] transpose(int[][] matrix){
for(int i = 0; i < N; i++) {
for(int j = i+1; j < N; j++) {
int temp = matrix[i][j];
matrix[i][j] = matrix[j][i];
matrix[j][i] = temp;
}
}
return matrix;
}
public static int[][] reverseRow(int[][] matrix){
for(int j = 0; j < N; j++){
for(int i = 0; i < N / 2; i++) {
int temp = matrix[j][i];
matrix[j][i] = matrix[j][N - i - 1];
matrix[j][N - i - 1] = temp;
}
}
return matrix;
}
public static int[][] reverseCol(int[][] matrix){
for(int col = 0;col < matrix[0].length; col++){
for(int row = 0; row < matrix.length/2; row++) {
int temp = matrix[row][col];
matrix[row][col] = matrix[matrix.length - row - 1][col];
matrix[matrix.length - row - 1][col] = temp;
}
}
return matrix;
}
問題的結構如下:我有原始數字的int [] []我有數字的int [] [],這是原始數字轉換的結果。 具體而言,順時針旋轉90度,順時針旋轉180度。
實際問題要大得多,但是我認為有一個規則不能直接獲得問題的答案,因此我將其縮減為我所需要的。
問題是這樣的:運行方法一后,原始數組被修改,因此在運行方法二之前它已損壞。
例如,方法一之前的原始:
1111
0000
0000
0000
方法一之后的原稿;
0001
0001
0001
0001
這些變化發生在我運行transpose(matrix)和reverseRow(matrix)之后。 請注意,在Java調試模式下,當我跳過這些方法時,可以看到原始內容已更改。 我什至沒有提到原來的。 我修改了原始版本的通過版本。
因此,有3個問題:
我以為傳遞給方法的對象不會被更改,除非您返回更改的對象,然后在main()或原始方法中將原始對象設置為更改的對象? 我不是在談論transpose或reverseRow,因為這些應該在方法One中更改矩陣。
我使用一種使用字符串的方法對此進行了測試。 我的上述信念是正確的。 int [] []不同嗎?
我該如何解決它,使原件不變? 還是我錯過了一些非常簡單的事情?
當您了解Java變量保存引用而不是對象時,這最容易理解。
而且這些引用始終按值傳遞,如前面的問題中所述, Java是“按引用傳遞”還是“按值傳遞”? 。
該答案解決了您的特定問題。
1)我認為傳遞給方法的對象不會被更改,除非您返回更改的對象,然后將原始對象設置為main()或原始方法中更改的對象?
對象不會傳遞給方法。 Java變量是對對象的引用 。 您可以復制Java變量而不復制對象。
如果將引用類型的變量傳遞給方法,則該方法無法修改您的變量。 但是,如果它是可變的,它可以修改變量引用的對象。
2)我測試了使用字符串的方法。 我的上述信念是正確的。 int [] []不同嗎?
數組是您要通過引用訪問的可變對象。
字符串是一個不可變的對象。 您可能正在嘗試通過分配給被調用方法的變量來更改調用者的變量。
3)如何修復它,使原件不被更改? 還是我錯過了一些非常簡單的事情?
您可以在將數組的引用傳遞給方法之前制作該數組的副本。
對一維數組執行此操作的一種方法是使用System.arraycopy() 。 您的二維數組是由多個一維數組構成的,因此您可以使用對System.arraycopy()
多次調用來復制它。
此問題討論了其他方法: 如何在Java中復制二維數組? 。 請注意,問題中接受的答案省略了創建二維數組的必要步驟。
在Java中,一切都是通過值傳遞的。 但是,令人困惑的是,該值保留了對原始對象的引用 。
分配變量只會更改輸入變量的引用:
void doSomething(String str){
str = "New String"; // str variable now holds a reference to "New String"
// however, the original String Object was not changed
}
但是,這不會更改原始字符串。 實際上,String和所有原語int,double等都是一個不可變的對象。這使我得出以下語句:
更改調用函數的輸入參數的唯一方法是調用該參數使對象發生突變的方法(例如param.setValue(newValue)
或param[0] = newValue
)。
這使我們可以進行一些觀察:
char
, int
, double
等)不能在調用函數中進行更改,因為它們不包含任何使數據變異的方法。 String
, Integer
, Double
等)永遠不能在函數中更改,因為根據定義,它們不包含使數據可變的方法。 StringBuilder
, BigInteger
, BigDecimal
等)只能通過在對象上調用mutator方法來更改(而不能通過重新分配變量來更改)。 對於數組,你能想到的array[0] = newValue
等作為上mutator方法Array
類似於list.set(0, newValue)
用於一個List
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.