Java入門教程十二(集合與泛型)

在 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接口

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集合

List 接口實現了 Collection 接口,它主要有兩個實現類:ArrayList 類和 LinkedList 類。在 List 集合中容許出現重複元素。與 Set 集合不一樣的是,在 List 集合中的元素是有序的,能夠根據索引位置來檢索 List 集合中的元素,第一個添加到 List 集合中的元素的索引爲 0,第二個爲 1,依此類推設計

ArrayList 類

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

LinkList類

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集合

Set 集合也實現了 Collection 接口,它主要有兩個實現類:HashSet 類和 TreeSet類。Set 集合中的對象不按特定的方式排序,只是簡單地把對象加入集合,集合中不能包含重複的對象,而且最多隻容許包含一個 null 元素

HashSet

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

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集合

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");

Collection類

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");
相關文章
相關標籤/搜索