隨筆-16  評(píng)論-50  文章-2  trackbacks-0

          在程序開發(fā)的過程,要交換兩個(gè)變量的內(nèi)容,是一種比較常見的事情。在排序算法中,就有一種就叫做“交換排序法”。在所有的排序算法,交換要排序的集合中的兩個(gè)元素,幾乎是必須的過程。在Java中交換兩個(gè)元素的內(nèi)容,如果你是程序員新手,你可能碰到意想不到的問題。

          首先,來看看交換下面的程序。為了交換兩個(gè)整數(shù)變量的內(nèi)容,寫了下面這樣的一個(gè)方法實(shí)現(xiàn):

          public void swap(int i, int j) {
              int t = i;
              i = j;
              j = t;
          }

          調(diào)用上面的方法,有問題嗎?

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

          在程序執(zhí)行此段代碼后,你會(huì)發(fā)現(xiàn),x還是100, y還是1。為什么呢?因?yàn)镴ava對(duì)方法參數(shù)的傳遞,是使用值調(diào)用(call by value)的。想想,如果我這樣調(diào)用swap函數(shù)呢,swap(3, 4),這是莫名其妙的,有誰會(huì)要交換3和4這兩個(gè)常數(shù)呢。

          那沒辦法交換兩個(gè)整數(shù)變量了嗎?可以。把swap函數(shù)體替換掉swap函數(shù)的調(diào)用就可以了。如:

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

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

           

          繼續(xù)討論函數(shù)調(diào)用吧。函數(shù)調(diào)用時(shí),參數(shù)傳遞的方式主要有兩種:

          • 值傳遞
          • 引用傳遞

          Java使用的是值傳遞。值傳遞是把變量的值、常數(shù)或常量傳遞給參數(shù)。而引用傳遞,是把變量的所在內(nèi)存中的地址傳遞給參數(shù),參數(shù)通過地址找到變量的值。很明顯,引用傳遞不能把常數(shù)傳遞給參數(shù)。值傳遞和引用傳遞還有一個(gè)很大的不同:對(duì)于像int這樣的小類型變量來說,值傳遞沒副作用,而引用傳遞有。也就是說,在函數(shù)調(diào)用的執(zhí)行過程中,不能改變傳遞給參數(shù)的變量的值。

          但對(duì)于普通類類型參數(shù)的傳遞方式的理解和原生類型有點(diǎn)不同。對(duì)于方法method(Object o)的調(diào)用method(x), 不是把對(duì)象x復(fù)制一份傳遞給參數(shù)o,而是把對(duì)象x的在內(nèi)存中的首地址,也就是把對(duì)象x的引用拷貝給參數(shù)o。這樣就能這樣實(shí)現(xiàn)對(duì)象的交換函數(shù)了嗎?

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

          答案是:No。因?yàn)橄裣旅孢@樣的調(diào)用:

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

          在執(zhí)行完上的代碼后,x指向的還是原來的X對(duì)象,y指向的還是那個(gè)Y對(duì)象。就像歌唱的那樣:星星還是那個(gè)星星,月亮還是那個(gè)月亮。

           

          難道就不能通過方法調(diào)用實(shí)現(xiàn)交換這個(gè)功能嗎?可以。有兩種辦法:

          • 可以交換數(shù)組等集合里的元素
          • 用反射實(shí)現(xiàn)

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

          用反射實(shí)現(xiàn)swap函數(shù),有點(diǎn)殺雞用大炮的感覺。性能不怎么樣,還容易出錯(cuò)。這個(gè)留著做家庭作業(yè)吧。

          posted on 2008-01-03 10:42 Jeff Lau 閱讀(1149) 評(píng)論(1)  編輯  收藏 所屬分類: Jeff On Java 2008

          評(píng)論:
          # re: 交換[未登錄] 2008-04-02 19:58 | Tom
          最后的swap(Object[] a, int i, int j)中第三個(gè)語句寫錯(cuò)了吧?
          應(yīng)該是a[j] = t;  回復(fù)  更多評(píng)論
            

          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 东丰县| 南开区| 大理市| 高雄县| 五莲县| 白河县| 甘肃省| 阿坝| 色达县| 中山市| 宜都市| 微山县| 徐州市| 白山市| 麻阳| 合阳县| 汝阳县| 山西省| 蓝山县| 阿尔山市| 乃东县| 根河市| 婺源县| 威远县| 巍山| 安吉县| 沂南县| 凯里市| 水富县| 卓尼县| 安远县| 成武县| 大渡口区| 石渠县| 汨罗市| 吉安县| 乌拉特前旗| 武陟县| 汪清县| 碌曲县| 蓬莱市|