在 Java 中數組的長度是不可修改的。然而在實際應用的不少狀況下,沒法肯定數據數量。這些數據不適合使用數組來保存,這時候就須要使用集合。java
Java 的集合就像一個容器,用來存儲 Java 類的對象。有些容器內部存放的東西在容器內部是不可操做的,像水瓶裏的水,除了將其裝入和倒出以外,就不能再進行別的操做了,可是很容易裝入和倒出;而有些容器內部存放的東西在容器內部是能夠操做的,例如,衣櫃裏面擺放的衣服,不只能夠將衣服存放到衣櫃中,還能夠將衣服有序地擺放,以便在使用時快速查找,可是卻不容易取出。Java 的集合類比這些容器功能還多,其中有些是方便放入和取出的,有些是方便查找的。在集合中常常會用到泛型來使集合更加安全。算法
集合類都位於 java.util 包,其中提供了一個表示和操做對象集合的統一構架,包含大量集合接口,以及這些接口的實現類和操做它們的算法。一個集合是一個對象,但它表示一組對象,Java 集合中實際存放的是對象的引用值,不能存放基本數據類型值。數組
集合框架是一個類庫的集合,包含實現集合的接口。接口是集合的抽象數據類型,提供對集合中所表示的內容進行單獨操做的可能。
Collection 接口:該接口是最基本的集合接口,一個 Collection 表明一個元素。
List 接口:該接口實現了 Collection 接口。List 是有序集合,容許有相同的元素。使用 List 可以精確地控制每一個元素插入的位置,用戶可以使用索引(元素在 List 中的位置,相似於數組下標)來訪問 List 中的元素,與數組相似。
Set 接口:該接口也實現了 Collection 接口。它不能包含重複的元素,SortedSet 是按升序排列的 Set 集合。
Map 接口:包含鍵值對,Map 不能包含重複的鍵。SortedMap 是一個按升序排列的 Map 集合。安全
Java 平臺提供了許多數據集接口的實現類。例如實現 Set 接口的經常使用類有 HashSet 和 TreeSet,它們均可以容納全部類型的對象,可是不能保證序列順序永久不變框架
實現 List 接口的經常使用類有 ArrayList 和 LinkedList,它們也能夠容納全部類型的對象包括 null,而且都保證元素的存儲位置。函數
實現 Map 映射的類是 HashMap,可實現一個鍵到值的映射。
HashSet:爲優化査詢速度而設計的 Set。它是基於 HashMap 實現的,HashSet 底層使用 HashMap 來保存全部元素,實現比較簡單。
TreeSet:該類不只實現了 Set 接口,還實現了 java.util.SortedSet 接口,該實現類是一個有序的 Set,這樣就能從 Set 裏面提取一個有序序列。
ArrayList:一個用數組實現的 List,能進行快速的隨機訪問,效率高並且實現了可變大小的數組。
LinkedList:對順序訪問進行了優化,但隨機訪問的速度相對較慢。此外它還有 addFirst()、addLast()、getFirst()、getLast()、removeFirst() 和 removeLast() 等方法,能把它當成棧(Stack)或隊列(Queue)來用。優化
Collection 接口是 List 接口和 Set 接口的父接口,一般狀況下不被直接使用。Collection 接口定義了一些通用的方法,經過這些方法能夠實現對集合的基本操做。由於 List 接口和 Set 接口繼承自 Collection 接口,因此也能夠調用這些方法this
boolean add(E e) 向集合中添加一個元素,E 是元素的數據類型 boolean addAll(Collection c) 向集合中添加集合 c 中的全部元素 void clear() 刪除集合中的全部元素 boolean contains(Object o) 判斷集合中是否存在指定元素 boolean containsAll(Collection c) 判斷集合中是否包含集合 c 中的全部元素 boolean isEmpty() 判斷集合是否爲空 Iterator<E>iterator() 返回一個 Iterator 對象,用於遍歷集合中的元素 boolean remove(Object o) 從集合中刪除一個指定元素 boolean removeAll(Collection c) 從集合中刪除全部在集合 c 中出現的元素 boolean retainAll(Collection c) 僅僅保留集合中全部在集合 c 中出現的元素 int size() 返回集合中元素的個數 Object[] toArray() 返回包含此集合中全部元素的數組
public static void main(Strmg[] args) { ArrayList list1=new ArrayList(); //建立集合 iist1 ArrayList list2=new ArrayList(); //建立集合 Iist2 list1.add("one"); //向 list1 添加一個元素 list1.add("two"); //向 list1 添加一個元素 list2.addAll(list1); //將 list1 的全部元素添加到 list2 list2.remove(0); //刪除第一個元素 }
List 接口實現了 Collection 接口,它主要有兩個實現類:ArrayList 類和 LinkedList 類。在 List 集合中容許出現重複元素。與 Set 集合不一樣的是,在 List 集合中的元素是有序的,能夠根據索引位置來檢索 List 集合中的元素,第一個添加到 List 集合中的元素的索引爲 0,第二個爲 1,依此類推設計
ArrayList 類提供了快速的基於索引的成員訪問方式,對尾部成員的增長和刪除支持較好。使用 ArrayList 建立的集合,容許對集合中的元素進行快速的隨機訪問code
ArrayList():構造一個初始容量爲 10 的空列表。 ArrayList(Collection<?extends E>c):構造一個包含指定 Collection 的元素的列表,這些元素是按照該 Collection 的迭代器返回它們的順序排列的。
ArrayList 類除了包含 Collection 接口中的全部方法以外,還包括 List 接口
E get(int index) 獲取此集合中指定索引位置的元素,E 爲集合中元素的數據類型 int index(Object o) 返回此集合中第一次出現指定元素的索引,若是此集合不包含該元 素,則返回 -1 int lastIndexOf(Obj ect o) 返回此集合中最後一次出現指定元素的索引,若是此集合不包含該 元素,則返回 -1 E set(int index, E element) 將此集合中指定索引位置的元素修改成 element 參數指定的對象。 此方法返回此集合中指定索引位置的原元素 List<E> subList(int fromlndex, int tolndex)返回一個新的集合,新集合中包含 fromlndex 和 tolndex 索引之間的全部元素。包含 fromlndex 處的元素,不包含 tolndex 索引處的元素
List list = new ArrayList(); list.add("1"); list.add("2"); list.add("3"); list.add("4"); list.get(0);//獲得1 List sublist=new ArrayList(); sublist=list.subList(0,2); //subList 爲1,2
LinkedList 類採用鏈表結構保存對象,這種結構的優勢是便於向集合中插入或者刪除元素。須要頻繁向集合中插入和刪除元素時,使用 LinkedList 類比 ArrayList 類效果高
LinkedList 類除了包含 Connection 接口和 List 接口
void addFirst(E e) 將指定元素添加到此集合的開頭 void addLast(E e) 將指定元素添加到此集合的末尾 E getFirst() 返回此集合的第一個元素 E getLast() 返回此集合的最後一個元素 E removeFirst() 刪除此集合中的第一個元素 E removeLast() 刪除此集合中的最後一個元素
LinkedList<String> products=new LinkedList<String>(); //建立集合對象 String product1=new String("product1"); String product2=new String("product2"); products.getFirst();//獲得product1
Set 集合也實現了 Collection 接口,它主要有兩個實現類:HashSet 類和 TreeSet類。Set 集合中的對象不按特定的方式排序,只是簡單地把對象加入集合,集合中不能包含重複的對象,而且最多隻容許包含一個 null 元素
HashSet 類是按照哈希算法來存儲集合中的元素,使用哈希算法能夠提升集合元素的存儲速度,當向 Set 集合中添加一個元素時,HashSet 會調用該元素的 hashCode() 方法,獲取其哈希碼,而後根據這個哈希碼計算出該元素在集合中的存儲位置,
HashSet():構造一個新的空的 Set 集合。 HashSet(Collection<? extends E>c):構造一個包含指定 Collection 集合元素的新 Set 集合。其中,「< >」中的 extends 表示 HashSet 的父類,即指明該 Set 集合中存放的集合元素類型。c 表示其中的元素將被存放在此 Set 集合中。 HashSet hs=new HashSet(); //調用無參的構造函數建立HashSet對象 HashSet<String> hss=new HashSet<String>(); //建立泛型的 HashSet 集合對象 String name=new String("HelloWorld"); String name1=new String("HelloWorld1"); hss(name); hss(name1);
若是向 Set 集合中添加兩個相同的元素,則後添加的會覆蓋前面添加的元素,即在 Set 集合中不會出現相同的元素
TreeSet 類同時實現了 Set 接口和 SortedSet 接口。SortedSet 接口是 Set 接口的子接口,能夠實現對集合升序排序。TreeSet 只能對實現了 Comparable 接口的類對象進行排序,由於 Comparable 接口中有一個 compareTo(Object o) 方法用於比較兩個對象的大小
包裝類(BigDecimal、Biglnteger、 Byte、Double、 Float、Integer、Long 及 Short) 按數字大小比較 Character 按字符的 Unicode 值的數字大小比較 String 按字符串中字符的 Unicode 值的數字大小比較
TreeSet 類除了實現 Collection 接口的全部方法以外,還有如下方法
E first() 返回此集合中的第一個元素。其中,E 表示集合中元素的數據 類型 E last() 返回此集合中的最後一個元素 E poolFirst() 獲取並移除此集合中的第一個元素 E poolLast() 獲取並移除此集合中的最後一個元素 SortedSet<E> subSet(E fromElement,E toElement) 返回一個新的集合,新集合包含原集合中 fromElement 對象與 toElement 對象之間的全部對象。包含 fromElemen t對象,不包含 toElement 對象 SortedSet<E> headSet<E toElement〉 返回一個新的集合,新集合包含原集合中 toElement 對象以前的全部對象。 不包含 toElement 對象 SortedSet<E> tailSet(E fromElement) 返回一個新的集合,新集合包含原集合中 fromElement 對象以後的全部對 象。包含 fromElement 對象
TreeSet<Double> treeSet=new TreeSet<Double>(); treeSet.add(0.02); treeSet.add(0.01); treeSet.add(0.03); for(int i=0;i<treeSet.toArray().length;i++) { System.out.print(treeSet.toArray.toArray()[i]); //依次輸出 0.01,0.02,0.03 } SortedSet<Double> headTreeSet =scores.headSet(0.02); //headTreeSet內只有0.01
天然排序時只能向 TreeSet 集合中添加相同數據類型的對象,不然會拋出 ClassCastException 異常
Map 是一種鍵-值對(key-value)集合,Map 集合中的每個元素都包含一個鍵對象和一個值對象。其中,鍵對象不容許重複,而值對象能夠重複,而且值對象還能夠是 Map 類型的,Map 接口主要有兩個實現類:HashMap 類和 TreeMap 類。其中,HashMap 類按哈希算法來存取鍵對象,而 TreeMap 類能夠對鍵對象進行排序
Map 接口中提供的經常使用方法
V get(Object key) 返回 Map 集合中指定鍵對象所對應的值。V 表示值的數據類型 V put(K key, V value) 向 Map 集合中添加鍵-值對,返回 key 之前對應的 value,若是沒有, 則返回 null V remove(Object key) 從 Map 集合中刪除 key 對應的鍵-值對,返回 key 對應的 value,如 果沒有,則返回null Set entrySet() 返回 Map 集合中全部鍵-值對的 Set 集合,此 Set 集合中元素的數據 類型爲 Map.Entry Set keySet() 返回 Map 集合中全部鍵對象的 Set 集合
Map map=new HashMap(); map.put("1","HelloWorld"); map.put("2","HelloWorld");
Collections 類提供了許多操做集合的靜態方法,藉助這些靜態方法能夠實現集合元素的排序、填充和複製等操做
sort() 方法主要有以下兩種重載形式。
void sort(List list):根據元素的天然順序對集合中的元素進行升序排序。 void sort(List list,Comparator comparator):按 comparator 參數指定的排序方式對集合中的元素進行排序。 List test=new ArrayList(); test.add(2); test.add(1); test.add(3); Collections.sort(test); //此時數組爲1,2,3
調用 reverse() 靜態方法能夠對指定集合元素進行逆向排序
void reverse(List list) //對集合中的元素進行反轉排序 List test=new ArrayList(); test.add(2); test.add(1); test.add(3); Collections.reverse(test); //此時數組爲3,2,1
Collections 類的 copy() 靜態方法用於將指定集合中的全部元素複製到另外一個集合中
void copy(List <? super T> dest,List<? extends T> src) List srcList=new ArrayList(); destList.add("1"); destList.add("2"); List destList=new ArrayList(); Collections.copy(destList,srcList);//此時destList爲1,2
Collections 類的 fill() 靜態方法能夠對指定集合的全部元素進行填充操做
void fill(List<? super T> list,T obj) //使用指定元素替換指定列表中的全部元素 List test=new ArrayList(); test.add("1"); test.add("2"); Collections.fill(srcList,"0"); //此時List裏全是0
泛型能夠在編譯的時候檢查類型安全,而且全部的強制轉換都是自動和隱式的,提升了代碼的重用率。
泛型本質上是提供類型的「類型參數」,也就是參數化類型。咱們能夠爲類、接口或方法指定一個類型參數,經過這個參數限制操做的數據類型,從而保證類型轉換的絕對安全。
public class Person{ private String name; public Person(String _name) { this.name=_name; } } Map<Integer, Person> persons=new HashMap<Integer, Person>(); //定義泛型 Map 集合 persons.add(new Person("HelloWorld"));
Map<Integer, Person> persons =new HashMap<Integer, Person>();」建立了一個鍵類型爲 Integer、值類型爲 Person 的泛型集合,即指明瞭該 Map 集合中存放的鍵必須是 Integer 類型、值必須爲 Person 類型,不然編譯出錯。
Person preson = persons.get(0);//在獲取 Map 集合中的元素時,不須要將"persons.get(id);"獲取的值強制轉換爲 Person 類型,程序會隱式轉換
除了能夠定義泛型集合以外,還能夠直接限定泛型類的類型參數。
public class class_name<data_type1,data_type2,…>{} //泛型類通常用於類中的屬性類型不肯定的狀況下。 private data_type1 property_name1;
在實例化泛型類時,須要指明泛型類中的類型參數,並賦予泛型類屬性相應類型的值
public class Person<T>{ private T param; public T getParam(){ return param; } public void setParam(T _param){ this. param = _param; } } public class Employee{ //類型體 } public static void main(String[] args){ //約束爲整形 Person<Integer> intergerPerson = new Person<Integer>(); intergerPerson. setParam(1); //約束爲字符串類型 Person<String> intergerPerson1 = new Person<String>(); intergerPerson1. setParam("String"); //除基礎類型外,也能夠約束爲自定義類型 Person<Employee> intergerPerson2 = new Person<Employee>(); intergerPerson1. setParam(new Employee()); }
泛型類中的類型參數能夠有多個
public class Person<T,N,S>{ //使用同上 }
泛型一樣能夠在類中包含參數化的方法,而方法所在的類能夠是泛型類,也能夠不是泛型類。
泛型方法使得該方法可以獨立於類而產生變化。若是使用泛型方法能夠取代類泛型化,那麼就應該只使用泛型方法。另外,對一個 static 的方法而言,沒法訪問泛型類的類型參數。所以,若是 static 方法須要使用泛型能力,就必須使其成爲泛型方法。
[訪問權限修飾符][static][final]<類型參數列表>返回值類型方法名([形式參數列表]) public static<T> void Test(T t){ } String helloWorld = "HelloWorld"; Test("HelloWorld");