Java – Save Object with Arrays

來源:互聯網
上載者:User

儲存對象有很多種方式,數組在其中有什麼特別之處呢?數組和其它容器之間的區別主要有兩方面:效率和類型。第一,效率:在Java中,數組是一種效率最高的儲存和隨機訪問對象引用序列的方式。**數組就是一個簡單的線性序列。但當建立一個數組對象(將數組看作對象),數組的大小就被固定了,並且這個數組的生命週期也是不可改變的。通常是建立一個特定大小的數組,在空間不足的時候再建立一個新的數組,然後把舊數組中的所有引用移到新數組中。在C++中,容器類vector的確知道自己儲存的對象是何類型,不過它有一個缺點:C++中vector的操作符[]不做邊界檢查,所以可能會越界操作。而在Java中,無論使用數組或容器,都有邊界檢查。如果越界操作就會得到一個RuntimeException異常。RuntimeException異常通常說明是程式員的錯誤,因此你不必自己做越界檢查。多說一句,為了速度,C++的vector不會對每次存取做邊界檢查;而Java的數組和容器會因為時刻存在的邊界檢查帶來固定的效能開銷。第二,類型:只有數組擁有儲存基本類型的能力。List、Set和Map容器不以具體的類型來處理對象。還句話說,它們將所有對象都按Object類型處理。從某個角度來說,這種方式很好:你只需要構建一個容器,任意的Java對象都可以放入其中。數組可以放入容器,作為使用Java基本封裝類的常量,或者作為封裝在你自己的類中的可變值。這正是數組比通用容器優越的第二點:當你建立一個數組時,它只能儲存特定類型(數組可以儲存基本類型,容器則不能)。這意味著會在編譯時間做類型檢查,以防將錯誤的類型插入數組,或取出資料時弄錯類型。當然,無論在編譯時間還是運行時,Java都會阻止你向對象發送不恰當的訊息。所以,並不是說哪種方法更不安全,只是如果編譯時間就能夠指出錯誤,那麼程式可以運行得更快,也減少了程式的使用者被異常嚇著的可能性。考慮到效率與類型檢查,應該儘可能使用數組。然而,如果要解決更一般化的問題,數組就可能受到過多的限制。

數組是第一級對象無論使用哪種類型的數組,數群組識別碼其實只是一個引用,指向在堆中建立的一個真實對象,這個(數組)對象用以儲存指向其他對象的引用。唯讀成員length是數組對象的一部分,事實上這是數組中唯一一個可以訪問的欄位和方法;“[]”文法是訪問數組對象唯一的方式。下例說明初始化數組的各種方式,以及如何給指向數組的引用賦值,使之指向另一個數組對象。此例也說明,**對象數組和基本類型數組在使用上幾乎是相同的;唯一的區別就是對象數組儲存的是引用,基本類型數組直接儲存基本類型的值。

/** * Title:  * Description:  * Company: Augmentum Inc<br> * Copyright: 2008 (c) Thinking in Java<br> * @author: Forest He * @version: 1.0 */package com.augmentum.foresthe;class Weeble {} // A samll mythical creaturepublic class ArraySize {public static void main(String[] args) {/** * Arrays of objects */Weeble[] a;Weeble[] b = new Weeble[5];Weeble[] c = new Weeble[4];Weeble[] d = { new Weeble(), new Weeble(), new Weeble() };a = new Weeble[] { new Weeble(), new Weeble() };for (int i = 0; i < c.length; i++) if (c[i] == null) c[i] = new Weeble();System.out.println("a.length = " + a.length);System.out.println("b.length = " + b.length);System.out.println("c.length = " + c.length);System.out.println("d.length = " + d.length);a = d;System.out.println("a.length = " + a.length);/** * Arrays of primitives */int[] e;int[] f = new int[5];int[] g = new int[4];int[] h = { 11, 47, 93 };System.out.println("f.length = " + f.length);System.out.println("g.length = " + g.length);System.out.println("h.length = " + h.length);e = h;System.out.println("e.length = " + e.length);e = new int[] { 1, 2 };System.out.println("e.length = " + e.length);}} 
數組a是一個尚未初始化的局部變數,在你對它正確地初始化之前,編譯器不允許用此引用做任何事情。**數組b初始化為指向一個Weeble引用的數組,但其實並沒有Weeble對象置入數組中。然而,仍然可以訪問數組的大小,因為b指向一個合法的對象。這樣做有一個小缺點:你無法知道在此數組中確切地有多少元素,因為length只表示數組能夠容納多少元素。也就是說,length是數組的大小,而不是實際儲存的元素個數。新產生一個數組對象時,其中所有的引用被自動初始化為null;所以檢查其中的引用是否為null,即可知道數組的某個位置是否存有對象。數組c表明,數組對象在建立之後,隨即將數組的各個位置都賦值為Weeble對象。**數組d表明使用“聚集初始化”文法建立數組對象(隱式地使用new在堆中建立,就像數組c一樣),並且以Weeble對象將其初始化的過程,這些操作只用了一條語句。數組d採用的聚集初始化操作必須在定義d的位置使用,但若使用下面的文法:“動態聚集初始化”,則可以在任意位置建立和初始化數組對象。例如,假設方法hide()需要一個Weeble對象的數組作為輸入參數。可以如此調用:hide(d); 但也可以動態地建立將要作為參數傳遞的數組:hide(new Weeble[] { new Weeble(), new Weeble() }); 在很多情況下,此文法使得代碼書寫變得更方便。運算式:a = d; 說明如何將指向某個數組對象的引用賦給另一個數組對象,這與其他類型的對象引用沒有任何區別。ps:容器類只能儲存對象的引用。而數組可以直接儲存基本類型,還可以儲存對象的引用。在容器中可以使用“封裝”類,例如Integer、Double等,以把基本類型的值放入容器中。但是相對於基本類型,封裝器類使用起來很笨拙。此外,與封裝基本類型的容器相比,建立與訪問一個基本類型的數組效率更高。
返回一個數組C和C++不能返回一個數組,而只能返回指向數組的指標。但Java允許直接返回一個數組。而且返回一個數組與返回任何其他對象(實質上是返回引用)沒什麼區別。
/** * Title:  * Description:  * Company: Augmentum Inc<br> * Copyright: 2008 (c) Thinking in Java<br> * @author: Forest He * @version: 1.0 */package com.augmentum.foresthe;import java.util.Random;public class IceCream {private static Random rand = new Random();public static final String[] flavors = { "Chocolate", "Strawberry", "Vanilla Fudge Swirl", "Mint Chip", "Mocha Almond Fudge", "Rum Raisin", "Praline Cream", "Mud Pie"};/** * 返回數組的容量為n, 由傳入方法的參數決定 */public static String[] flavorSet(int n) {String[] results = new String[n];Boolean[] picked = new Boolean[flavors.length];for (int i = 0; i < flavors.length; i++) picked[i] = false;for (int i = 0; i < n; i++) {int t;/** * 保證不產生重複的隨機數 */dot = rand.nextInt(flavors.length);while(picked[t]);results[i] = flavors[t];picked[t] = true;}return results;}public static void main(String[] args) {for (int i = 0; i < 20; i++) {System.out.println("flavorSet(" + i + ") = ");String[] f1 = flavorSet(flavors.length);for (int j = 0; j < f1.length; j++) System.out.println("/t" + f1[j]);}}}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.