1. 程式人生 > >Java中兩個數交換的細節問題

Java中兩個數交換的細節問題

在碼程式碼過程中,兩個數交換是經常用到的,但在Java 中,如果忽略了值傳遞和引用傳遞就很容易出錯。

看一下兩個整數交換程式碼:

public void swap(int a,int b){
int t=a;
a=b;
b=t;
}

這是不能成功交換兩個數的,就算是C、C++也不行,因為這是通過值傳遞的方式實現交換的

int x = 100;
int y = 1;
swap(x, y);

    在程式執行此段程式碼後,你會發現,x還是100, y還是1。為什麼呢?因為Java對方法引數的傳遞,是使用值呼叫(call by value)的。想想,如果我這樣呼叫swap函式呢,swap(3, 4),這是莫名其妙的,有誰會要交換3和4這兩個常數呢。

那沒辦法交換兩個整數變量了嗎?可以。把swap函式體替換掉swap函式的呼叫就可以了。如:

int x = 100;
int y = 1;
int t = x;
x = y;
y = t;

Java中其他的原生型別(primitive type)的情況,和int的一樣。

而在C或C++中,是通過引用和指標來進行交換的:
void swap(int &a,int &b)//引用傳遞 
{
 int temp;
 temp = a;
 a = b;
 b = temp;
}
void swap(int *a,int *b)//指標,地址傳遞 
{
 int temp;
 temp = *a;
 *a = *b;

* b = temp;
}

那繼續討論java的函式呼叫吧。函式呼叫時,引數傳遞的方式主要有兩種:

  • 值傳遞
  • 引用傳遞

  Java使用的是值傳遞。值傳遞是把變數的值、常數或常量傳遞給引數。而引用傳遞,是把變數的所在記憶體中的地址傳遞給引數,引數通過地址找到變數的值。很明顯,引用傳遞不能把常數傳遞給引數。值傳遞和引用傳遞還有一個很大的不同:對於像int這樣的小型別變數來說,值傳遞沒副作用,而引用傳遞有。也就是說,在函式呼叫的執行過程中,不能改變傳遞給引數的變數的值。

   但對於普通類型別引數的傳遞方式的理解和原生型別有點不同。對於方法method(Object o)的呼叫method(x), 不是把物件x複製一份傳遞給引數o,而是把物件x的在記憶體中的首地址,也就是把物件x的引用拷貝給引數o。這樣就能這樣實現物件的交換函數了嗎?

public void swap(Object o, Object p) {
    Object t = o;
    o = p;
    p = t;
}

答案是:No。因為像下面這樣的呼叫:

Object x = X;
Object y = Y;
swap(x, y);

    在執行完上的程式碼後,x指向的還是原來的X物件,y指向的還是那個Y物件。

難道就不能通過方法呼叫實現交換這個功能嗎?可以。有兩種辦法:

1、 可以交換陣列等集合裡的元素

public void swap(Object[] a, int i, int j) {
    Object t = a[i] ;
    a[i] = a[j];
    a[j] = t;
}

2、用反射實現

用反射實現swap函式(略)

---EOF---


相關推薦

Java個數交換細節問題

在碼程式碼過程中,兩個數交換是經常用到的,但在Java 中,如果忽略了值傳遞和引用傳遞就很容易出錯。 看一下兩個整數交換程式碼: public void swap(int a,int b){int t

Java之求陣列個數之和

給定一個整數陣列 nums 和一個目標值 target,請你在該陣列中找出和為目標值的 兩個 整數。 你可以假設每種輸入只會對應一個答案。但是,你不能重複利用這個陣列中同樣的元素。 示例: 給定 nums = [2, 7, 11, 15], target

java個數百分比,精確到指定位數

sta number ring light tin blog div clas imu // 獲取百分比,不帶小數點 private String getPercentage(String num, String total){ NumberFor

個數個數的和為N,找出這個數字的下標

完整 進行 代碼 ray 由於 比較 返回 put else 分析,兩個數字的和為N。那麽這兩個數字是否是唯一的呢?輸出的下標是否是第一對出現的呢? 1,我們假設這兩個數字是唯一的 和是唯一的,那麽其中一個數字越大,另一個數字就越小。想到大小關系,我們就想到了排序。那麽首先

java個字符串如何比較大小

blog 順序 body ring 差值 int print compare gpo 使用 String.compareTo 方法:compareTo() 的返回值是int, 它是先比較對應字符的大小(ASCII碼順序)1、如果字符串相等返回值02、如果第一個字符和

JAVA面試要點011---java個數的n次方怎麼寫

    JAVA技術交流QQ群:170933152   第一步我們首先檢視一下Math數學函式的API,可以看到pow()方法返回第一個引數的第二個引數次方,格式為Math.pow(m,n),代表m的n次方,如下圖所示: 

Java個byte型別相加結果賦值給byte型別的變數會報編譯錯誤,byte加byte的結果為什麼是int?

背景: 之前偶然看到有討論這個問題,在網上搜了半天,結果都不盡如人意,解釋沒有到位, 有的說byte加byte預設就是int,那為什麼這麼做呢? 這不是找麻煩麼?這種奇怪的預設還有哪些?帶來一些列疑問。。。。。。 有的說byte儲存的就是整型資料,這種說法的對錯姑且不論,至少我覺得難免有

資料結構演算法題/陣列個數相減(前面減後面)的最大值

陣列中兩個數相減(前面減後面)的最大值。 解法一:O(n^2) 就是一個很普通的方法。求出 陣列中所有下標小的元素減去下標大的元素,找出其中的最大值即可。程式碼如下: //O(N^2) 找出陣列arr中兩個數相減的最大值     public static int m

java字串比較--compareTo方法

java.lang.String.compareTo()方法比較兩個字串的字典,比較是基於字串中的每個字元的Unicode值 String n1 = "1"; String n2 = "0.15656655856565"; String m1 = "a"; String m2 = "b"; Strin

Java種比較器的實現

程式輸出結果:  為了讓大家較全,我把結果拷貝下來,如下:  通過內部比較器實現:  [id:1,salary=4500.0, id:2,salary=5000.0, id:4,salary=3500.0, id:4,salary=4000.0, id:5,salary=3000.0]  通過外部比較器實現:

C/C++ 個數交換引發的連環案

1. 一般法        如何交換兩個數?一般來說,交換兩個數需要藉助中間變數,即先令中間變數temp存放其中一個數a,然後再把另一個數b賦值給已被轉移資料的a,最後把存有a上午中間變數賦值給b,這樣a和b就完成了交換。下段程式碼就實現了這個功能: #include &

LeetCode:一個數個數的和

Given an array of integers, return indices of the two numbers such that they add up to a specific target. You may assume that each input

java種轉換時間的方法

將String ->util date - > sql date 在學過mvc後,可以新建一個工具類,把轉換程式碼寫到util包中 public class DateUtil { private static SimpleDateFormat sdf = new Sim

java個時間相減

間隔=Date1.getTime()-Date2.getTime();得出來的是毫秒數. 除1000是秒,再除60是分,再除60是小時. SimpleDateFormat myFormatter = new SimpleDateFormat( "yyyy-MM-dd "

個數交換的三種方法

比如 a=3;b=8; 用三種方法來交換兩個數的值? 第一種      定義一個臨時比變數儲存 :                    int temp = a;                 a = b;               b = temp; 第二種  

指標函式完成個數交換

#include<stdio.h> void swap(int *x,int *y) { int t; t=*x; *x=*y; *y=t; } main() { int a,b; int *p1,*p2;

有序陣列個數的和等於一個輸入值的函式

/*data[] 為有序陣列, length 為陣列的長度 sum為使用者輸入的和 num1 為符合和等於sum的第一個數 num2 為第二個數*/ #include<iostream> using namespace std; bool FindTwoNumbersWithSum(int dat

Java種多執行緒實現方式的區別

在程式開發中用到多執行緒,正統的方法是使用Runnable介面,相比繼承Thread類,Runnable介面有以下兩點好處: 1、避免單繼承機制的侷限,一個類可以實現多個介面 2、適用於資源的共享 下面以買票程式為例,分析繼承Thread類和實現Runnable介面的不同;

java個等號跟三個等號的區別?

首先,== equality 等同,=== identity 恆等。 ==, 兩邊值型別不同的時候,要先進行型別轉換,再比較。 ===,不做型別轉換,型別不同的一定不等。下面分別說明: 先說 ===,這個比較簡單。下面的規則用來判斷兩個值是否===相等: 1、如果型別不同,就

個數交換的3種方法(異或法有陷阱!)

最常用的方法,程式碼如下: int a=50,b=22,t; t=a; a=b; b=t;不使用額外空間的方法:(1)加減法 (2)異或法 (1)加減法程式碼如下: int a=50,b=22,t; a=a+b; b=a-b; a=a-b; (2)異或法(是兩數交換所用時間最快的方法) 顧名思義,就是將兩個數