官术网_书友最值得收藏!

3.3.4 數(shù)組工具Arrays

數(shù)組作為一種組合形式的數(shù)據(jù)類型,必然要求提供一些處理數(shù)組的簡便辦法,包括數(shù)組比較、數(shù)組復(fù)制、數(shù)組排序等。為此,Java專門設(shè)計(jì)了Arrays工具,該工具包含幾個(gè)常用方法,方便程序員加工數(shù)組。Arrays工具的常見方法簡述如下:

  • Arrays.equals(a1,a2); 判斷a1和a2兩個(gè)數(shù)組是否相等,也就是每個(gè)元素是否都相等。
  • Arrays.fill(a,val); 往數(shù)組a中填入指定的數(shù)值val。
  • dest=Arrays.copyOf(src,newLength); 把數(shù)組src的內(nèi)容賦值給數(shù)組dest,且dest的長度為newLength。
  • Arrays.sort(a); 對數(shù)組a的內(nèi)部元素排序,默認(rèn)按照升序排序。

下面詳細(xì)介紹以上4個(gè)數(shù)組處理方法的使用。

1.Arrays.equals方法

前面說過,雙等號“==”可用來判斷兩個(gè)變量的數(shù)值是否相等,但只適合基本變量類型之間的比較,例如比較兩個(gè)整型變量是否相等、兩個(gè)雙精度數(shù)是否相等、兩個(gè)布爾變量是否相等。若兩個(gè)數(shù)組變量通過“==”判斷相等與否,則比較的是這兩個(gè)數(shù)組是否為同一個(gè)數(shù)組,而不是比較兩個(gè)數(shù)組的所有元素是否都相等。要想判斷兩個(gè)數(shù)組內(nèi)部的每個(gè)元素是否一一相等,就必須通過Arrays工具的equals方法來辨別。equals方法返回true表示兩個(gè)數(shù)組的所有元素都相等,返回false表示兩個(gè)數(shù)組至少有一個(gè)元素不相等。

2.Arrays.fill方法

在聲明數(shù)組變量的時(shí)候,經(jīng)常需要對它初始化賦值,比如書店進(jìn)了10本書,每本書的售價(jià)都是99元,那么按照常規(guī)寫法只能書寫10遍99,就像下面的代碼這樣:

        // 構(gòu)造一個(gè)包含10個(gè)99的數(shù)組變量
        int[] prices={99, 99, 99, 99, 99, 99, 99, 99, 99, 99};

顯然輸入重復(fù)的數(shù)字是個(gè)負(fù)擔(dān),尤其重復(fù)數(shù)量很多的時(shí)候更甚。現(xiàn)在利用Arrays的fill方法,只需一行代碼即可對該數(shù)組的所有元素都填上相同的數(shù)值,于是數(shù)組的初始賦值代碼便優(yōu)化為下面這樣(完整代碼見本章源碼的src\com\control\array\ArrayFill.java):

        int[] prices=new int[10];      // 聲明一個(gè)整型數(shù)組,數(shù)組大小為10
        Arrays.fill(prices, 99);          // 給整型數(shù)組的每個(gè)元素全部填寫99
        for (int price : prices) {      // 循環(huán)遍歷并打印整型數(shù)組的所有元素?cái)?shù)值
            System.out.println("price="+price);
        }

3.Arrays.copyOf方法

把一個(gè)數(shù)組變量賦值給另一個(gè)數(shù)組變量,似乎可以用等號直接賦值,這在一般情況下沒有問題,但如果賦值之后修改了原數(shù)組的某個(gè)元素,就會出現(xiàn)問題了。譬如以下的演示代碼,先把數(shù)組變量pricesOrigin賦值給pricesAssign,接著修改原數(shù)組pricesOrigin的元素值,再打印新數(shù)組pricesAssign的所有元素(完整代碼見本章源碼的src\com\control\array\ArrayCopy.java):

        int[] pricesOrigin={99, 99, 99, 99, 99};// 聲明一個(gè)整型數(shù)組,數(shù)組大小為5,且5個(gè)元素全為99
        // 復(fù)制數(shù)組的第一個(gè)辦法:利用等號直接賦值。新數(shù)組只是原數(shù)組的別名
        int[] pricesAssign=pricesOrigin;
        pricesOrigin[1]=80;
        for (int price : pricesAssign) {  // 循環(huán)遍歷并打印整型數(shù)組的所有元素?cái)?shù)值
            System.out.println("assign price="+price);
        }

運(yùn)行以上的演示代碼,完整的日志輸出如下:

assign price=99

assign price=80

assign price=99

assign price=99

assign price=99

沒想到打印出來的第二個(gè)數(shù)組元素竟然變了,可是演示代碼明明只改了原數(shù)組pricesOrigin,并未修改新數(shù)組pricesAssign?讓測試程序錯(cuò)亂的緣故是數(shù)組之間的等號賦值相當(dāng)于給數(shù)組起一個(gè)別名,并非從頭到尾完整復(fù)制一個(gè)新數(shù)組出來。既然只是起了別名,那么實(shí)際上還是原名稱所指的數(shù)組,無非是該數(shù)組有兩個(gè)名字罷了。

顯然這種情況不是程序員期望的結(jié)果,程序員的本意是復(fù)制另外的數(shù)組,新數(shù)組不再與原數(shù)組有任何關(guān)聯(lián),大家井水不犯河水,互不干涉、互不影響,最好克隆一個(gè)一模一樣的新數(shù)組出來。Java恰巧給每個(gè)數(shù)組變量都提供了clone方法,該方法正是拿來克隆數(shù)組用的。克隆出來的新數(shù)組分配了單獨(dú)的存儲空間,并且數(shù)組元素的數(shù)值與原數(shù)組完全一致,如此便實(shí)現(xiàn)了正常意義上的數(shù)組賦值功能。利用clone方法復(fù)制數(shù)組變量的示例代碼如下:

        // 復(fù)制數(shù)組的第二個(gè)辦法:調(diào)用原數(shù)組的clone方法。新數(shù)組由原數(shù)組克隆而來
        int[] pricesClone=pricesOrigin.clone();
        pricesOrigin[1]=80;
        for (int price : pricesClone) {  // 循環(huán)遍歷并打印整型數(shù)組的所有元素?cái)?shù)值
            System.out.println("clone price="+price);
        }

運(yùn)行以上示例代碼,得到下面的日志輸出結(jié)果:

clone price=99

clone price=99

clone price=99

clone price=99

clone price=99

可見此時(shí)修改了原數(shù)組的元素值,并沒有改變新數(shù)組的元素值,真正做到了完整的復(fù)制操作。

clone方法正如其名,它把原數(shù)組的所有元素一個(gè)不漏地全部復(fù)制到新數(shù)組,這意味著,如果只想復(fù)制部分元素給新數(shù)組,clone方法就無能為力了。為此,Java給Arrays工具增配了一個(gè)copyOf方法,該方法允許從來源數(shù)組復(fù)制若干元素給目標(biāo)數(shù)組。當(dāng)待復(fù)制的元素個(gè)數(shù)恰好等于原數(shù)組的大小時(shí),copyOf方法的作用等同于數(shù)組變量的clone方法。下面是通過copyOf方法將數(shù)組原樣復(fù)制到新數(shù)組的代碼例子:

        // 復(fù)制數(shù)組的第3個(gè)辦法:調(diào)用Arrays工具的copyOf方法。允許復(fù)制部分元素
        int[] pricesCopy=Arrays.copyOf(pricesOrigin, pricesOrigin.length);
        for (int price : pricesCopy) {  // 循環(huán)遍歷并打印整型數(shù)組的所有元素?cái)?shù)值
            System.out.println("copy price="+price);
        }

從上面的代碼看到,copyOf方法后面跟著兩個(gè)參數(shù):第一個(gè)參數(shù)是原數(shù)組的名稱;第二個(gè)參數(shù)是要復(fù)制的元素個(gè)數(shù)。接下來,把第二個(gè)參數(shù)改小一點(diǎn),看看copyOf方法是否真的支持只復(fù)制部分元素。于是第二個(gè)參數(shù)改為pricesOrigin.length-1之后的代碼如下:

        // 改變copyOf方法的第二個(gè)參數(shù)值,允許復(fù)制指定大小的數(shù)組元素
        int[] pricesPart=Arrays.copyOf(pricesOrigin, pricesOrigin.length-1);
        for (int price : pricesPart) {  // 循環(huán)遍歷并打印整型數(shù)組的所有元素?cái)?shù)值
            System.out.println("part price="+price);
        }

重新運(yùn)行修改后的數(shù)組復(fù)制代碼,日志輸出結(jié)果如下:

part price=99

part price=99

part price=99

part price=99

可以看到新數(shù)組的元素只有4個(gè),而原數(shù)組共有5個(gè)元素,說明此時(shí)的確只復(fù)制了部分元素。

Arrays工具的copyOf方法還有一個(gè)妙用,比如有一個(gè)數(shù)組分配了初始大小為5,現(xiàn)在想把該數(shù)組的長度擴(kuò)大到10,這時(shí)利用copyOf方法就能動態(tài)調(diào)整數(shù)組的大小。具體做法是:調(diào)用copyOf方法時(shí),來源數(shù)組和目標(biāo)數(shù)組都填該數(shù)組的名稱,然后待復(fù)制的元素大小填寫擴(kuò)大后的長度。下面的代碼將演示如何將某數(shù)組的大小增大一位:

        // 把copyOf方法的返回值賦給原數(shù)組,可以動態(tài)調(diào)整該數(shù)組的大小
        pricesOrigin=Arrays.copyOf(pricesOrigin, pricesOrigin.length+1);
        for (int price : pricesOrigin) {  // 循環(huán)遍歷并打印整型數(shù)組的所有元素?cái)?shù)值
            System.out.println("origin price="+price);
        }

運(yùn)行調(diào)整數(shù)組大小的演示代碼,觀察到以下的日志輸出:

origin price=99

origin price=99

origin price=99

origin price=99

origin price=99

origin price=0

由此可見,數(shù)組大小果然增大了一位,并且新增的數(shù)組元素值為0,這正是整型變量的默認(rèn)數(shù)值。

4.Arrays.sort方法

顧名思義,Arrays工具的sort方法是給數(shù)組元素排序的,并且默認(rèn)的排序結(jié)果為升序。sort方法用起來很簡單,只要把待排序的數(shù)組名稱填進(jìn)圓括號,編譯器就會自動完成該數(shù)組的排序任務(wù)。舉一個(gè)給整型數(shù)組排序的例子,簡單的Java實(shí)現(xiàn)代碼如下:

        int[] prices={ 99, 80, 18, 68, 8 };
        // 對整型數(shù)組prices里的元素排序,sort方法得到的結(jié)果是升序排列
        Arrays.sort(prices);
        for (int price : prices) {  // 循環(huán)遍歷并打印整型數(shù)組的所有元素?cái)?shù)值
            System.out.println("price=" + price);
        }

運(yùn)行上述的排序代碼,得到下面的結(jié)果日志:

price=8

price=18

price=68

price=80

price=99

從日志看到,排序后的數(shù)組元素從小到大打印,很明顯這是升序排列。

當(dāng)然,在前面的例子中,數(shù)組元素早在聲明數(shù)組時(shí)便初始化賦值了,實(shí)戰(zhàn)性不強(qiáng)。接下來,嘗試動態(tài)生成一個(gè)隨機(jī)數(shù)數(shù)組,再對該數(shù)組排序,這樣更貼近實(shí)際業(yè)務(wù)。詳細(xì)的實(shí)現(xiàn)代碼涉及數(shù)組、循環(huán)、冒號跳轉(zhuǎn)等技術(shù),有興趣的讀者不妨動手實(shí)踐。下面是生成隨機(jī)數(shù)組并對其排序的代碼例子(完整代碼見本章源碼的src\com\control\array\ArraySort.java):

        int[] numbers=new int[10];  // 創(chuàng)建一個(gè)大小為10的整型數(shù)組
        loop: for (int i=0; i < numbers.length; i++) {
            int item=new Random().nextInt(100);  // 生成一個(gè)小于100的隨機(jī)整數(shù)
            // 下面的循環(huán)用來檢查數(shù)組中是否已經(jīng)存在該隨機(jī)數(shù)
            for (int j=0; j < i; j++) {
                if (numbers[j] == item) {
                                 // 若已經(jīng)存在該隨機(jī)數(shù),則繼續(xù)第一層循環(huán),重新生成隨機(jī)數(shù)
                    i--;              // 本次循環(huán)做了無用功,取消當(dāng)前的計(jì)數(shù)
                    continue loop;      // 繼續(xù)以loop標(biāo)記的外層循環(huán)
                }
            }
            numbers[i]=item;      // 若原數(shù)組不存在該隨機(jī)數(shù),則把隨機(jī)數(shù)加入數(shù)組中
        }
        // 對整型數(shù)組numbers里的元素排序,sort方法得到的結(jié)果是升序排列
        Arrays.sort(numbers);
        for (int number : numbers) {  // 循環(huán)遍歷并打印整型數(shù)組的所有隨機(jī)數(shù)
            System.out.println("number=" + number);
        }
主站蜘蛛池模板: 蒲江县| 罗源县| 青海省| 芷江| 将乐县| 佛山市| 息烽县| 鄱阳县| 郯城县| 高要市| 子洲县| 昌吉市| 饶阳县| 辽阳县| 涿州市| 民丰县| 仁布县| 华亭县| 得荣县| 张家港市| 北海市| 古蔺县| 南华县| 茶陵县| 和林格尔县| 偏关县| 阿图什市| 定西市| 莱芜市| 高邑县| 江门市| 革吉县| 凌海市| 沂水县| 青河县| 浦东新区| 丁青县| 鄂温| 台湾省| 开远市| 拜城县|