所有集合類都位于java.util包下。集合中只能保存對象(保存對象的引用變量)。(數組既可以保存基本類型的數據也可以保存對象)。
當我們把一個對象放入集合中后,系統會把所有集合元素都當成Object類的實例進行處理。從JDK1.5以后,這種狀態得到了改進:可以使用泛型來限制集合里元素的類型,并讓集合記住所有集合元素的類型(參見具體泛型的內容)。
Java的集合類主要由兩個接口派生而出:Collection和Map,Collection和Map是Java集合框架的根接口,這兩個接口又包含了一些接口或實現類。

Set和List接口是Collection接口派生的兩個子接口,Queue是Java提供的隊列實現,類似于List。

Map實現類用于保存具有映射關系的數據(key-value)。
Set、List和Map可以看做集合的三大類。
List集合是有序集合,集合中的元素可以重復,訪問集合中的元素可以根據元素的索引來訪問。
Set集合是無序集合,集合中的元素不可以重復,訪問集合中的元素只能根據元素本身來訪問(也是集合里元素不允許重復的原因)。
Map集合中保存Key-value對形式的元素,訪問時只能根據每項元素的key來訪問其value。
對于Set、List和Map三種集合,最常用的實現類分別是HashSet、ArrayList和HashMap三個實現類。
2、Collection接口Collection接口是List、Set和Queue接口的父接口,同時可以操作這三個接口。
Collection接口定義操作集合元素的具體方法大家可以參考API文檔,Collection 是任何對象組,元素各自獨立,通常擁有相同的套用規則。
基本操:
增加元素add(Object obj); addAll(Collection c);
刪除元素 remove(Object obj);removeAll(Collection c);
求交集 retainAll(Collection c);
刪除元素 remove(Object obj);removeAll(Collection c);
求交集 retainAll(Collection c);
Set接口的三個具體類是:
HashSet--基于散列表的集,加進散列表的元素要實現hashCode()方法
LinkedHashSet--對集迭代時,按增加順序返回元素
TreeSet--基于(平衡)樹的數據結構

1. 繼承結構java.lang.Object |_ java.util.AbstractCollection<E> |_ java.util.AbstractSet<E> |_ java.util.HashSet<E>2. 主要方法 add(Object) addAll(Collection) remove(object) removeAll(Collection) size() iterator() toArray() clear() isEmpty() contain(object) containAll(Collection)
Set集合中不允許出現相同的項,Set集合在用Add()方法添加一個新項時,首先會調用equals(Object o)來比較新項和已有的某項是否相等,而不是用==來判斷相等性,所以對于字符串等已重寫equals方法的類,是按值來比較相等性的
下面的程序創建了一個散列集來存儲字符串,并且使用一個迭代器來遍歷這個規則集中的元素:
public class Main{    public static void main(String args[]) {        Set<String> set = new HashSet<String>();        set.add("London");        set.add("Paris");        set.add("New York");        set.add("New York");        set.add("Beijing");        set.add("Guangzhou");        System.out.PRintln(set);                Iterator<String> iterator = set.iterator();        while(iterator.hasNext()) {            System.out.print(iterator.next().toUpperCase() + " ");        }    }}注意:字符串沒有按照順序存儲,因為散列集中的元素是沒有特定的順序的
當然也可以不使用迭代器,而用for-each循環來簡化上面的迭代代碼:
for(Object i: set) System.out.print(i);
由于一個規則集是Collection的一個實例,所有定義在Collection中的方法都可以用在規則集上,下面的代碼就是一個例子:
public class Main{    public static void main(String args[]) {        Set<String> set1 = new HashSet<String>();                set1.add("London");        set1.add("Paris");        set1.add("New York");        set1.add("San Francisco");        set1.add("Beijing");        set1.add("Guangzhou");                System.out.println(set1);        System.out.println(set1.size() + "elements in set1");                set1.remove("London");        System.out.println("/nset1 is " + set1);        System.out.println(set1.size() + " elements in set1");                Set<String> set2 = new HashSet<String>();        set2.add("London");        set2.add("Shanghai");        set2.add("Paris");                System.out.println("/nset2 is " + set2);        System.out.println(set2.size() + " elements in set2");                System.out.println("/nIs Taipei in set2? " + set2.contains("Taipei"));        set1.addAll(set2);        System.out.println("/nafter adding set2 to set1, set1 is " + set1);        set1.removeAll(set2);        System.out.println("After removing set2 from set1, set1 is " + set1);        set1.retainAll(set2);  //保留共有的元素        System.out.println("After removing common elements in set2 " + "from set1, set1 is " + set1);    }}運行結果如下:
[San Francisco, New York, Guangzhou, Paris, Beijing, London]6elements in set1
set1 is [San Francisco, New York, Guangzhou, Paris, Beijing]5 elements in set1
set2 is [Shanghai, Paris, London]3 elements in set2
Is Taipei in set2? false
after adding set2 to set1, set1 is [San Francisco, New York, Guangzhou, Shanghai, Paris, Beijing, London]After removing set2 from set1, set1 is [San Francisco, New York, Guangzhou, Beijing]After removing common elements in set2 from set1, set1 is []
鏈式散列集--LinkedHashSetLinkedHashSet,顧名思義,就是在Hash的實現上添加了Linked的支持。對于LinkedHashSet,在每個節點上通過一個鏈表串聯起來,這樣,就可以保證確定的順序。對于希望有常量復雜度的高效存取性能要求、同時又要求排序的情況下,可以直接使用LinkedHashSet。
LinkedHashSet用一個鏈表實現來擴展HashSet類,它支持對規則集內的元素的排序。HashSet中的元素是沒有被排序的它實現了Set接口。存入Set的每個元素必須是唯一的,因為Set不保存重復元素。但是Set接口不保證維護元素的次序。Set與Collection有完全一樣的接口Iterable,同時Set繼承了Collection。LinkedHashSet具有HashSet的查詢速度,且內部使用鏈表維護元素的順序(插入的順序),于是在使用迭代器遍歷Set時,結果會按元素插入的次序顯示。下面是一個測試程序:
public class Main{    public static void main(String args[]) {        Set<String> set = new LinkedHashSet<String>();        set.add("London");        set.add("Paris");        set.add("New York");        set.add("San Francisco");        set.add("Beijing");        set.add("New York");                System.out.println(set);        for(Object i: set)            System.out.print(i.toString().toLowerCase() + " ");    }}如果不需要維護元素被插入的順序,就應該使用HashSet,它會比LinkedHashSet更加的高效
樹形集TreeSet繼承結構:
java.lang.Object|_java.util.AbstractCollection<E>|_java.util.AbstractSet<E>|_java.util.TreeSet<E>類聲明:publicclassTreeSet<E>extendsAbstractSet<E>implementsSortedSet<E>,Cloneable,java.io.Serializable //它實現了sortedSet,有排序的功能
TreeSet的主要性質
1、TreeSet中不能有重復的元素;
2、TreeSet具有排序功能;
3、TreeSet中的元素必須實現Comparable接口并重寫compareTo()方法,TreeSet判斷元素是否重復、以及確定元素的順序靠的都是這個方法;
4、對于java類庫中定義的類,TreeSet可以直接對其進行存儲,如String,Integer等(因為這些類已經實現了Comparable接口);
java常用類實現Comparable接口,并提供了比較大小的標準。實現Comparable接口的常用類:
BigDecimal、BigIneger以及所有數值型對應包裝類:按它們對應的數值的大小進行比較。
Character:按字符的UNICODE值進行比較。
Boolean:true對應的包裝類實例大于false對應的包裝類實例。
String:按字符串中字符的UNICODE值進行比較。
Date、Time:后面的時間、日期比前面的時間、日期大。
public class Main{    public static void main(String args[]) {        Set<String> set = new HashSet<String>();        set.add("London");        set.add("Paris");        set.add("New York");        set.add("San Francisco");        set.add("Beijing");        set.add("New York");                TreeSet<String> treeSet = new TreeSet<String>(set);        System.out.println("Sorted tree set: " + treeSet);                //下面的方法在SortedSet接口        System.out.println("first(): " + treeSet.first());  //返回第一個元素        System.out.println("last(): " + treeSet.last());  //返回最后一個元素        System.out.println("headSet(): " + treeSet.headSet("New York"));  //返回New York之前的所有元素        System.out.println("tailSet(): " + treeSet.tailSet("New York"));   //返回New York 及其之后的所有元素                //使用NavigableSet接口里面的方法        System.out.println("lower(/"p/"): " + treeSet.lower("P"));   //返回小于"P"的最大元素        System.out.println("higher(/"p/"): " + treeSet.higher("P"));   //返回大于"P"的最小元素        System.out.println("floor(/"p/"): " + treeSet.floor("P"));  //返回小于等于"P"的最大元素        System.out.println("ceiling(/"p/"): " + treeSet.ceiling("P"));  //返回大于等于"P"的最小元素        System.out.println("pollFirst(/"p/"): " + treeSet.pollFirst());   //刪除第一個元素,并返回被刪除的元素        System.out.println("pollLast(/"p/"): " + treeSet.pollLast());  //刪除最后一個元素,并返回被刪除的元素        System.out.println("New tree set: " + treeSet);    }}運行結果如下:
Sorted tree set: [Beijing, London, New York, Paris, San Francisco]first(): Beijinglast(): San FranciscoheadSet(): [Beijing, London]tailSet(): [New York, Paris, San Francisco]lower("p"): New Yorkhigher("p"): Parisfloor("p"): New Yorkceiling("p"): ParispollFirst("p"): BeijingpollLast("p"): San FranciscoNew tree set: [London, New York, Paris]
比較器接口Comparator有時希望將元素插入到一個樹集合中,這些元素可能不是java.lang.Comparable的實例,這時可以定義一個比較容器來比較這些元素
Comparetor接口有兩個方法:compare和equals
public int compare(Object element1, Object element2);
如果element1小于element2,就返回一個負值,如果大于就返回一個正值,若相等,則返回0;
public boolean equals(Objectelement);
如果指定對象也是一個比較器,并且與這個比較器具有相同的排序,則返回true
public class Main{    public static void main(String args[]) {        Person a[] = new Person[4];        a[0] = new Person("zhangsan", 11);        a[1] = new Person("lisi", 23);        a[2] = new Person("wangwu", 33);        a[3] = new Person("wuzhong", 26);        compareName cn = new compareName();        compareAge ca = new compareAge();        for(int i = 0; i < a.length; i++) a[i].print();        System.out.println();        System.out.println("sorting by age:");        Arrays.sort(a, ca);        for(int i = 0; i < a.length; i++) a[i].print();        System.out.println();        System.out.println("sorting by name:");        Arrays.sort(a, cn);        for(int i = 0; i < a.length; i++) a[i].print();    }}class Person {    public String name;    public int age;    Person(String n, int a) {        name = n;        age = a;    }    public void print() {        System.out.println("Name is " + name + ", Age is " + age);    }}class compareAge implements Comparator<Person> {    public int compare(Person p1, Person p2) {        if (p1.age > p2.age)  return -1;        else if (p1.age < p2.age) return 1;        else return 0;    }}class compareName implements Comparator<Person> {    public int compare(Person p1, Person p2) {        return p1.name.compareTo(p2.name);    }}運行結果:
Name is zhangsan, Age is 11Name is lisi, Age is 23Name is wangwu, Age is 33Name is wuzhong, Age is 26
sorting by age:Name is wangwu, Age is 33Name is wuzhong, Age is 26Name is lisi, Age is 23Name is zhangsan, Age is 11
sorting by name:Name is lisi, Age is 23Name is wangwu, Age is 33Name is wuzhong, Age is 26Name is zhangsan, Age is 11
新聞熱點
疑難解答