數組為什么這么特殊
1.數組與其他容器之間的區(qū)別有三個方面:效率、類型和保存基本類型的能力。在Java中,數組是一種效率最高的存儲和隨機訪問對象引用序列的方式。數組就是一個簡單的線性序列,這使得元素的訪問非常快速。但是為這種速度所付出的 代價是數組對象大小被固定,并且在其生命周期中不可改變。
2.隨著自動包裝機制的出現,容器已經能與數組幾乎一樣方便地用于基本類型中了。數組僅存的優(yōu)點就是效率。然而,如果要解決更加一般化的問題,那數組就可能收到過多的限制,因此在這些情況下還是會使用容器。
數組是第一級對象
1.數組的制度成員length是數組對象的一部分,表示此數組對象可以存儲多少元素,也就是說,length是數組的大小,而不是實際保存的元素。因此通過length詢問數組的大小有一個缺點:你無法知道數組中確切地有多少個元素。
2.新生成一個數組對象時,其中所有的引用被自動初始化為null,所以檢查其中引用是否為null,即可知道數組的某個位置是否存有對象。同樣的,如果數組中的對象是基本類型,就會被自動初始化為相應的值。
返回一個數組
1.假設要寫一個方法,而且希望它返回不止一個值,而是一組值。在Java中只需要直接“返回一個數組”,無需對數組負責——只要需要它,它就會一直存在,當使用完之后,垃圾回收器會清理掉它。
多維數組
1.Java SE5中的Arrays.deepToString()方法,可以將多維數組轉換為多個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.數組中構成矩陣的每個向量都可以具有任意長度(這被稱為粗糙數組)。
數組與泛型
1.通常數組與泛型不能很好地結合。你不能實例化具有參數化類型的數組。擦除會移除參數類型信息,而數組必須知道它們所持有的確切類型,以強制保證類型安全。
2.可以參數化數組本身的類型:
public <T> T[] f(T[] arg) {
return arg;
}
3.編譯器確實不能讓你實例化泛型數組,但是,它允許你創(chuàng)建對這種數組的引用:
List<String>[] ls; //Success
ls = new ArrayList<String>[10]; //Illegal
盡管不能創(chuàng)建實際的持有泛型的數組對象,但是你可以創(chuàng)建非泛型的數組,然后將其轉型:
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>();
}
}
問題是數組是協變類型的,因此List<String>[]也是一個Object[],并且你可以利用這一點,將一個ArrayList<Integer>賦值到你的數組中,而不會有任何編譯期或運行時錯誤。
創(chuàng)建測試數據
一.Arrays.fill()
Java標準類庫Arrays有一個作用十分有限的fill()方法:只能用同一個值填充哥哥位置,針對對象而言就是膚質同一個引用進行填充:
int[] a = new int[6];
Arrays.fill(a, 11);
String[] s = new String[6];
Arrays.fill(s, 3, 5, "Hello");
使用Arrays.fill()可以填充整個數組,或者只填充數組的某個區(qū)域。但是由于只能用單一的數值來調用Arrays.fill(),因此所產生的結果并非特別有用。
二.數據生成器
1.為了以靈活的方式創(chuàng)建更有意義的數組,我們可以引用Generator的概念。如果某個工具使用了Generator,那么久就可以通過選擇Generator的類型來創(chuàng)建任何類型的數據。
Arrays實用功能
一.復制數組
1.Java標準類庫提供有static方法System.arraycopy(),用它復制數組比用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()需要的參數有:源數組,表示從源數組中的什么位置開始復制的偏移量,表示從目標數組的什么位置開始復制的偏移量,以及需要復制的元素個數。注意避免數組越界操作。
2.System.arraycopy()不會執(zhí)行自動包裝和自動拆包。
二.數組的比較
1.Arrays類提供了重載后的equals()方法,用來比較整個數組。數組相等的條件是元素個數必須相等,并且對應位置的元素也相等,這可以通過對每一個元素使用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
三.數組元素的比較
1.Java有兩種方式來提供比較功能,第一種是實現java.lang.Comparable接口,并實現compareTo()方法,使你的類具有天生的比較能力。第二種是創(chuàng)建一個實現了Comparator接口的類,實現compare()方法,有特殊需要時重寫equals()方法。
四.數組排序
1.使用內置的排序方法,就可以對任意的基本類型數組進行排序;也可以對人意的對象數組進行排序,只要該對象實現了Comparable接口或具有相關聯的Comparator:
String[] sa = {"Java", "C++", "Python"};
Arrays.sort(sa);
Java標準類庫中的排序算法針對正排序的特殊類型進行了優(yōu)化——針對基本類型設計的“快速排序”,以及針對對象設計的“穩(wěn)定歸并排序”。所以無須擔心排序的性能。
五.在已排序的數組中查找
1.如果數組已經排好序了,就可以使用Arrays.binarySearch()執(zhí)行快速查找。如果要對味排序的數組使用,那么就會產生不可預料的結果:
int[] a = {1, 2, 3, 4, 5};
Arrays.sort(a);
int position = Arrays.binarySearch(a, 3);
2.如果找到了目標,Arrays.binarySearch()產生的返回值等于或大于0.否則,它產生負返回值,表示若要保持數組的排序狀態(tài)此目標元素所應該插入的位置。這個負值的計算方式為:
- (插入點) - 1
插入點是指,第一個大雨查找對象的元素在數組中的位置。
3.搜索算法不是專為包含重復元素的數組而設計的,雖然仍可用,但是無法保證找到的是這些副本中的哪一個。