《Thinking in Java》學(xué)習(xí)——16章數(shù)組

數(shù)組為什么這么特殊

1.數(shù)組與其他容器之間的區(qū)別有三個(gè)方面:效率、類型和保存基本類型的能力。在Java中,數(shù)組是一種效率最高的存儲和隨機(jī)訪問對象引用序列的方式。數(shù)組就是一個(gè)簡單的線性序列,這使得元素的訪問非常快速。但是為這種速度所付出的 代價(jià)是數(shù)組對象大小被固定,并且在其生命周期中不可改變。
2.隨著自動包裝機(jī)制的出現(xiàn),容器已經(jīng)能與數(shù)組幾乎一樣方便地用于基本類型中了。數(shù)組僅存的優(yōu)點(diǎn)就是效率。然而,如果要解決更加一般化的問題,那數(shù)組就可能收到過多的限制,因此在這些情況下還是會使用容器。

數(shù)組是第一級對象

1.數(shù)組的制度成員length是數(shù)組對象的一部分,表示此數(shù)組對象可以存儲多少元素,也就是說,length是數(shù)組的大小,而不是實(shí)際保存的元素。因此通過length詢問數(shù)組的大小有一個(gè)缺點(diǎn):你無法知道數(shù)組中確切地有多少個(gè)元素。
2.新生成一個(gè)數(shù)組對象時(shí),其中所有的引用被自動初始化為null,所以檢查其中引用是否為null,即可知道數(shù)組的某個(gè)位置是否存有對象。同樣的,如果數(shù)組中的對象是基本類型,就會被自動初始化為相應(yīng)的值。

返回一個(gè)數(shù)組

1.假設(shè)要寫一個(gè)方法,而且希望它返回不止一個(gè)值,而是一組值。在Java中只需要直接“返回一個(gè)數(shù)組”,無需對數(shù)組負(fù)責(zé)——只要需要它,它就會一直存在,當(dāng)使用完之后,垃圾回收器會清理掉它。

多維數(shù)組

1.Java SE5中的Arrays.deepToString()方法,可以將多維數(shù)組轉(zhuǎn)換為多個(gè)String

public class ThreeDWithNew {
    public static void main(String... args) {
        int[][][] a = new int[2][2][4];
        System.out.println(Arrays.deepToString(a));
    }
}
/* Output:
[[[0, 0, 0, 0], [0, 0, 0, 0]], [[0, 0, 0, 0], [0, 0, 0, 0]]]
*/

2.數(shù)組中構(gòu)成矩陣的每個(gè)向量都可以具有任意長度(這被稱為粗糙數(shù)組)。

數(shù)組與泛型

1.通常數(shù)組與泛型不能很好地結(jié)合。你不能實(shí)例化具有參數(shù)化類型的數(shù)組。擦除會移除參數(shù)類型信息,而數(shù)組必須知道它們所持有的確切類型,以強(qiáng)制保證類型安全。
2.可以參數(shù)化數(shù)組本身的類型:

public  <T> T[] f(T[] arg) {
    return arg;
}

3.編譯器確實(shí)不能讓你實(shí)例化泛型數(shù)組,但是,它允許你創(chuàng)建對這種數(shù)組的引用:

List<String>[] ls; //Success
ls = new ArrayList<String>[10]; //Illegal

盡管不能創(chuàng)建實(shí)際的持有泛型的數(shù)組對象,但是你可以創(chuàng)建非泛型的數(shù)組,然后將其轉(zhuǎn)型:

public class ArrayOfGenerics {
    @SupressWarning("unchecked")
    public static void main(String... args) {
        List<String> ls;
        List[] la = new List[10];
        ls = (List<String>[]) la; //unchecked warning
        ls[0] = new ArrayList<String>();
    }
}

問題是數(shù)組是協(xié)變類型的,因此List<String>[]也是一個(gè)Object[],并且你可以利用這一點(diǎn),將一個(gè)ArrayList<Integer>賦值到你的數(shù)組中,而不會有任何編譯期或運(yùn)行時(shí)錯(cuò)誤。

創(chuàng)建測試數(shù)據(jù)

一.Arrays.fill()

Java標(biāo)準(zhǔn)類庫Arrays有一個(gè)作用十分有限的fill()方法:只能用同一個(gè)值填充哥哥位置,針對對象而言就是膚質(zhì)同一個(gè)引用進(jìn)行填充:

int[] a = new int[6];
Arrays.fill(a, 11);

String[] s = new String[6];
Arrays.fill(s, 3, 5,  "Hello");

使用Arrays.fill()可以填充整個(gè)數(shù)組,或者只填充數(shù)組的某個(gè)區(qū)域。但是由于只能用單一的數(shù)值來調(diào)用Arrays.fill(),因此所產(chǎn)生的結(jié)果并非特別有用。

二.數(shù)據(jù)生成器

1.為了以靈活的方式創(chuàng)建更有意義的數(shù)組,我們可以引用Generator的概念。如果某個(gè)工具使用了Generator,那么久就可以通過選擇Generator的類型來創(chuàng)建任何類型的數(shù)據(jù)。

Arrays實(shí)用功能

一.復(fù)制數(shù)組

1.Java標(biāo)準(zhǔn)類庫提供有static方法System.arraycopy(),用它復(fù)制數(shù)組比用for循環(huán)要快得多。System.arraycopy()針對所有類型做了重載:

int[] i = new int[7];
int[] j = new int[5];
Arrays.fill(j, 100);
System.arraycopy(i, 0, j, 0, j.length);

arraycopy()需要的參數(shù)有:源數(shù)組,表示從源數(shù)組中的什么位置開始復(fù)制的偏移量,表示從目標(biāo)數(shù)組的什么位置開始復(fù)制的偏移量,以及需要復(fù)制的元素個(gè)數(shù)。注意避免數(shù)組越界操作。
2.System.arraycopy()不會執(zhí)行自動包裝和自動拆包。

二.數(shù)組的比較

1.Arrays類提供了重載后的equals()方法,用來比較整個(gè)數(shù)組。數(shù)組相等的條件是元素個(gè)數(shù)必須相等,并且對應(yīng)位置的元素也相等,這可以通過對每一個(gè)元素使用equals()作比較來判斷:

int[] a1 = new int[10];
int[] a2 = new int[10];
Arrays.fill(a1, 10);
Arrays.fill(a2, 10);
print(Arrays.equals(a1, a2)); //Output : true
三.數(shù)組元素的比較

1.Java有兩種方式來提供比較功能,第一種是實(shí)現(xiàn)java.lang.Comparable接口,并實(shí)現(xiàn)compareTo()方法,使你的類具有天生的比較能力。第二種是創(chuàng)建一個(gè)實(shí)現(xiàn)了Comparator接口的類,實(shí)現(xiàn)compare()方法,有特殊需要時(shí)重寫equals()方法。

四.數(shù)組排序

1.使用內(nèi)置的排序方法,就可以對任意的基本類型數(shù)組進(jìn)行排序;也可以對人意的對象數(shù)組進(jìn)行排序,只要該對象實(shí)現(xiàn)了Comparable接口或具有相關(guān)聯(lián)的Comparator

String[] sa = {"Java", "C++", "Python"};
Arrays.sort(sa);

Java標(biāo)準(zhǔn)類庫中的排序算法針對正排序的特殊類型進(jìn)行了優(yōu)化——針對基本類型設(shè)計(jì)的“快速排序”,以及針對對象設(shè)計(jì)的“穩(wěn)定歸并排序”。所以無須擔(dān)心排序的性能。

五.在已排序的數(shù)組中查找

1.如果數(shù)組已經(jīng)排好序了,就可以使用Arrays.binarySearch()執(zhí)行快速查找。如果要對味排序的數(shù)組使用,那么就會產(chǎn)生不可預(yù)料的結(jié)果:

int[] a = {1, 2, 3, 4, 5};
Arrays.sort(a);
int position = Arrays.binarySearch(a, 3);

2.如果找到了目標(biāo),Arrays.binarySearch()產(chǎn)生的返回值等于或大于0.否則,它產(chǎn)生負(fù)返回值,表示若要保持?jǐn)?shù)組的排序狀態(tài)此目標(biāo)元素所應(yīng)該插入的位置。這個(gè)負(fù)值的計(jì)算方式為:
- (插入點(diǎn)) - 1
插入點(diǎn)是指,第一個(gè)大雨查找對象的元素在數(shù)組中的位置。
3.搜索算法不是專為包含重復(fù)元素的數(shù)組而設(shè)計(jì)的,雖然仍可用,但是無法保證找到的是這些副本中的哪一個(gè)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容