Java編程思想 數組總結

數組爲什麼特殊
數組與其他種類的容器之間的區別有三方面 效率 類型和保存基本類型的能力
數組可以持有基本類型 而泛型之前的容器則不能 但是有了泛型 容器就可以指定並檢查它們所持有對象的類型 並且有了自動包裝機制 容器看起來還能夠持有基本類型 下面是將數組與泛型容器進行比較的示例
在這裏插入圖片描述
在這裏插入圖片描述

數組是第一級對象
下例總結了初始化數組的各種方式 以及如何對指向數組的引用賦值 使之指向另一個數組對象 此例也說明 對象數組和基本類型數組在使用上幾乎是相同的 唯一的區別就是對象數組保存的是引用 基本類型數組直接保存基本類型的值
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

返回一個數組
下例演示如何返回String型數組
在這裏插入圖片描述
在這裏插入圖片描述

多維數組
創建多維數組很方便 對於基本類型的多維數組 可以通過使用花括號將每個向量分隔開
在這裏插入圖片描述

下面的示例使用了Java SE5的Arrays.deepToString()方法 它可以將多維數組轉換爲多個String 正如從輸出中所看到的那樣 還可以使用new來分配數組 下面的三維數組就是在new表達式中分配的
在這裏插入圖片描述

數組中構成矩陣的每個向量都可以具有任意的長度(這被稱爲粗糙數組)
在這裏插入圖片描述

可以用類似的方式處理非基本類型的對象數組 下面 你可以看到如何用花括號把多個new表達式組織到一起
在這裏插入圖片描述
在這裏插入圖片描述

自動包裝機制對數組初始化器也起作用
在這裏插入圖片描述

下面的示例展示了可以如何逐個地 部分地構建一個非基本類型的對象數組
在這裏插入圖片描述

Arrays.deepToString()方法對基本類型數組和對象數組都起作用
在這裏插入圖片描述
在這裏插入圖片描述

數組與泛型
通常 數組與泛型不能很好地結合 你不能實例化具有參數化類型的數組
在這裏插入圖片描述
擦除會移除參數類型信息 而數組必須知道它們所持有的確切類型 以強制保證類型安全
但是 你可以參數化數組本身的類型
在這裏插入圖片描述

正如上例所證明的那樣 不能創建泛型數組這一說法並不十分準確 誠然 編譯器確實不讓你實例化泛型數組 但是 它允許你創建對這種數組的引用 例如
在這裏插入圖片描述
這條語句可以順利地通過編譯器而不報任何錯誤 而且 儘管你不能創建實際的持有泛型的數組對象 但是你可以創建非泛型的數組 然後將其轉型
在這裏插入圖片描述

一般而言 你會發現泛型在類或方法的邊界處很有效 而在類或方法的內部 擦除通常會使泛型變得不適用 例如 你不能創建泛型數組
在這裏插入圖片描述

創建測試數據

Arrays.fill()
Java標準類庫Arrays有一個作用十分有限的fill()方法 只能用同一個值填充各個位置 而針對對象而言 就是複製同一個引用進行填充 下面是一個示例
在這裏插入圖片描述
在這裏插入圖片描述

數據生成器
首先給出的是可以用於所有基本類型的包裝器類型 以及String類型的最基本的計數生成器集合 這些生成器類都嵌套在CountingGenerator類中 從而使得它們能夠使用與所要生成的對象類型相同的名字 例如 創建Integer對象的生成器可以通過表達式new CountingGenerator.Integer()來創建
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

下面是一個測試工具 針對嵌套的Generator這一慣用法 因爲使用了反射所以這個工具可以遵循下面的形式來測試Generator的任何集合
在這裏插入圖片描述
在這裏插入圖片描述

下面是一組使用隨機數生成器的Generator 因爲Random構造器使用常量進行初始化 所以 每次用這些Generator中的一個來運行程序時 所產生的輸出都是可重複的
在這裏插入圖片描述
在這裏插入圖片描述

爲了不生成過大的數字 RandomGenerator.Integer默認使用的模數爲10000 但是重載的構造器允許你選擇更小的值 同樣的方式也應用到了RandomGenerator.Long上 對於Float和Double生成器 小數點之後的數字被截掉了
我們複用GeneratorTest來測試RandomGenerator
在這裏插入圖片描述
在這裏插入圖片描述

從Generator中創建數組
爲了接收Generator併產生數組 我們需要兩個轉換工具 第一個工具使用任意的Generator來產生Object子類型的數組 爲了處理基本類型 第二個工具接收任意基本類型的包裝器類型數組 併產生相應的基本類型數組
第一個工具有兩種選項 並由重載的靜態方法array()來表示 該方法的第一個版本接收一個已有的數組 並使用某個Generator來填充它 而第二個版本接收一個Class對象 一個Generator和所需的元素數量 然後創建一個新數組 並使用所接收的Generator來填充它 注意 這個工具只能產生Object子類型的數組 而不能產生基本類型數組
在這裏插入圖片描述
CollectionData類將創建一個Collection對象 該對象中所填充的元素是由生成器gen產生的 而元素的數量則由構造器的第二個參數確定 所有的Collection子類型都擁有toArray()方法 該方法將使用Collection中的元素來填充參數數組
第二個方法使用反射來動態創建具有恰當類型和數量的新數組 然後使用與第一個方法相同的技術來填充該數組
我們可以使用在前面定義的CountingGenerator類中的某個生成器來測試Generated
在這裏插入圖片描述
在這裏插入圖片描述

泛型不能用於基本類型 而我們確實想用生成器來填充基本類型數組 爲了解決這個問題 我們創建了一個轉換器 它可以接收任意的包裝器對象數組 並將其轉換爲相應的基本類型數組 如果沒有這個工具 我們就必須爲所有的基本類型創建特殊的生成器
在這裏插入圖片描述
在這裏插入圖片描述

下面的示例展示瞭如何將ConvertTo應用於兩個版本的Generated.array()上
在這裏插入圖片描述

下面的程序將使用RandomGenerator中的類來測試這些數組生成工具
在這裏插入圖片描述
在這裏插入圖片描述

Arrays實用功能
Java標準類庫提供有static方法System.arraycopy() 用它複製數組比用for循環複製要快很多 System.arraycopy()針對所有類型做了重載 下面的例子就是用來處理int數組的
在這裏插入圖片描述
在這裏插入圖片描述

這個例子說明基本類型數組與對象數組都可以複製 然而 如果複製對象數組 那麼只是複製了對象的引用 而不是對象本身的拷貝 這被稱作淺複製(shallow copy)
System.arraycopy()不會執行自動包裝和自動拆包 兩個數組必須具有相同的確切類型

數組的比較
Arrays類提供了重載後的equals()方法 用來比較整個數組 同樣 此方法針對所有基本類型與Object都做了重載 數組相等的條件是元素個數必須相等 並且對應位置的元素也相等 這可以通過對每一個元素使用equals()作比較來判斷(對於基本類型 需要使用基本類型的包裝器類的equals()方法 例如 對於int類型使用Integer.equals()作比較)見下例
在這裏插入圖片描述
在這裏插入圖片描述

數組元素的比較
Java有兩個方式來提供比較功能 第一種是實現java.lang.Comparable接口 使你的類具有 天生 的比較能力 此接口很簡單 只有compareTo()一個方法 此方法接收另一個Object爲參數 如果當前對象小於參數則返回負值 如果相等則返回零 如果當前對象大於參數則返回正值
下面的類實現了Comparable接口 並且使用Java標準類庫的方法Arrays.sort()演示了比較的效果
在這裏插入圖片描述
在這裏插入圖片描述

Collection類包含一個reverseOrder()方法 該方法可以產生一個Comparator 它可以反轉自然的排序順序 這很容易應用於CompType
在這裏插入圖片描述
在這裏插入圖片描述
也可以編寫自己的Comparator 在這裏的CompType對象是基於j值而不是基於i值的
在這裏插入圖片描述

數組排序
使用內置的排序方法 就可以對任意的基本類型數組排序 也可以對任意的對象數組進行排序 只要該對象實現了Comparator接口或具有相關聯的Comparator 下面的例子生成隨機的String對象 並對其排序
在這裏插入圖片描述

在已排序的數組中查找
如果數組已經排好序了 就可以使用Arrays.binarySearch()執行快速查找 如果要對未排序的數組使用binarySearch() 那麼將產生不可預料的結果 下面的例子使用RandIntGenerator.Integer填充數組 然後再使用同樣的生成器生成要查找的值
在這裏插入圖片描述
在這裏插入圖片描述

如果使用Comparator排序了某個對象數組(基本類型數組無法使用Comparator進行排序) 在使用binarySearch()時必須提供同樣的Comparator(使用binarySearch()方法的重載版本) 例如 可以修改StringSorting.java程序以進行某種查找
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章