集合(Collection解析 Set List Map三大集合運用)


集合的概念:

         集合是 包含多個對象的簡單對象,所包含的對象稱為元素。集合里面可以包含任意多個對象,數量可以變化;同時對對象的類型也沒有限制,也就是說集合里面的所有對象的類型可以相同,也可以不同。

集合與數組的特點對比:

集合:數量不限、類型不限
數組:定長、類型單一

“集合框架”由一組用來操作對象的接口組成,不同接口描述不同類型的組

數據存儲結構分類:

 

(1)順序存儲             (2)鏈式存儲        (3)樹形存儲      (4)散列存儲Hash    (5)Map映射存儲


 

 

接口

實現

歷史集合類

Set

HashSet

 

TreeSet

 

List

ArrayList

Vector

LinkedList

Stack

Map

HashMap

Hashtable

TreeMap

Properties

集合框架中各接口的特點:

1:Collection接口               是一組允許重復的對象。

2:Set接口                            繼承Collection,無序但不允許重復。

3:List接口                            繼承Collection,有序但允許重復,並引入位置下標。

4:Map接口                          既不繼承Set也不繼承Collection,是鍵值對。

Collection接口:

    用於表示任何對象或元素組。想要盡可能以常規方式處理一組元素時,就使用這一接口。

用此接口必須要它的實現類,如
Collection<T> col=new HashSet<T>(0);
 
collection接口具有如下函數操作:
方法摘要
 boolean add(E e) 
          確保此 collection 包含指定的元素(可選操作)。
 boolean addAll(Collection<? extends E> c) 
          將指定 collection 中的所有元素都添加到此 collection 中(可選操作)。
 void clear() 
          移除此 collection 中的所有元素(可選操作)。
 boolean contains(Object o) 
          如果此 collection 包含指定的元素,則返回 true
 boolean containsAll(Collection<?> c) 
          如果此 collection 包含指定 collection 中的所有元素,則返回 true
 boolean equals(Object o) 
          比較此 collection 與指定對象是否相等。
 int hashCode() 
          返回此 collection 的哈希碼值。
 boolean isEmpty() 
          如果此 collection 不包含元素,則返回 true
 Iterator<E> iterator() 
          返回在此 collection 的元素上進行迭代的迭代器。
 boolean remove(Object o) 
          從此 collection 中移除指定元素的單個實例,如果存在的話(可選操作)。
 boolean removeAll(Collection<?> c) 
          移除此 collection 中那些也包含在指定 collection 中的所有元素(可選操作)。
 boolean retainAll(Collection<?> c) 
          僅保留此 collection 中那些也包含在指定 collection 的元素(可選操作)。
 int size() 
          返回此 collection 中的元素數。
 Object[] toArray() 
          返回包含此 collection 中所有元素的數組。
<T> T[]
toArray(T[] a) 
          返回包含此 collection 中所有元素的數組;返回數組的運行時類型與指定數組的運行時類型相同。
  
Set接口:
          按照定義,Set接口繼承Collection接口,而且它不允許集合中存在重復項。所有原始方法都是Collection中現成的,沒有引入新方法
 
HashSet接口
  1.  
    <pre name= "code" class="java">//可初定義容量大小為0
  2.  
    //Set是接口,必須new它的實現類
  3.  
    //HashSet是一組不
  4.  
    Set<Object> set= new HashSet<Object>(0);
  5.  
    Set<Object> set2= new HashSet<Object>(0);
  6.  
    Person p1= new Person("張三",20);
  7.  
    Person p2= new Person("李四",22);
  8.  
    Person p3= new Person("王五",24);
  9.  
    Person p4= new Person("Jack",30);
  10.  
    Person p5= new Person("Tom",20);
  11.  
    Person p6= new Person("Swite",13);
  12.  
    Person p7= new Person("Pick",16);
  13.  
    Person p8= new Person("錢七",32);
  14.  
    //添加元素,集合容量會增加(JAVA類中有操作),返回型boolean
  15.  
    //注意添加的是元素的地址,改變集合中的一個元素,另一集合的相同元素同樣改變
  16.  
    //添加順序是根據Hash算法排序的,因此需要實現添加元素的hashCode和equals函數
  17.  
    //不然按該元素的內存地址排序
  18.  
    set.add(p1);set2.add(p1);
  19.  
    System.out.println(set.add(p1)); //返回FALSE,已加入元素不會重復添加
  20.  
    set.add(p5);set2.add(p5);
  21.  
    set.add(p6);set2.add(p6);
  22.  
    set.add(p4);set2.add(p7);
  23.  
    set.add(p2);set2.add(p8);
  24.  
    set.add(p3);
  25.  
    //在set2中元素全部加入,有添加的元素,返回true
  26.  
    set.addAll(set2);
  27.  
    //將集合的所有元素清空
  28.  
    set.clear();
  29.  
    //判斷集合中有無此元素,有則返回true,
  30.  
    set.contains(p1);
  31.  
    //判斷集合set2中的元素是否在set集合中都有,返回boolean值
  32.  
    set.containsAll(set2);
  33.  
    //判斷參數對象與此對象的相等性
  34.  
    set.equals(p1); //false(即使集合中只有p1,也不會相等,因為是不同對象)
  35.  
    //若倆個集合中的元素相等,則倆個集合相等,
  36.  
    set.equals(set2); //false
  37.  
    //判斷集合是否是空
  38.  
    set.isEmpty();
  39.  
    //獲得集合元素的個數
  40.  
    set.size();
  41.  
    //移除集合的某一個元素,返回boolean值,沒有則返回false
  42.  
    set.remove(p1);
  43.  
    //移除既在參數集合中存在,又在此集合中存在的元素,取差集,返回值boolean值
  44.  
    set.removeAll(set2);
  45.  
    //移除不存在參數集合中的本集合元素,取交集,返回值boolean值
  46.  
    set.retainAll(set2);
  47.  
    //返回集合的迭代器,以便搜索集合的元素
  48.  
    //因為HashSet是按哈希值存儲,不便直接定位
  49.  
    Iterator<Object> it =set.iterator();
  50.  
    while(it.hasNext()){
  51.  
    //依次輸出集合的每一個元素的toString()
  52.  
    System.out.println(it.next());
  53.  
    }


 
        
TreeSet
是一組能夠排序的的集合,但是要注意:
1:被添加的元素必須實現comparator接口
2:覆蓋其中的compareTo函數
3:后添加的元素會調動自身的compareTo函數,與集合中已有元素進行比較(集合按從小到大排序),一般會將其強轉成相同類比較(除非自己寫時准許)
4:java中有14類實現了comparator接口,分別是:
             1、BigDecimal,BigInteger,Byte,Double,Float,Integer,Long,Short按數字大小排序
             2、Character 按Unicode值的數字大小排序
             3、CollationKey 按語言環境敏感的字符串排序
             4、Date 按年代排序
             5、File 按系統特定的路徑名的全限定字符的Unicode值排序
             6、ObjectStreamField 按名字中字符的Unicode值排序
             7、String 按字符串中字符Unicode值排序
5:當集合元素不實現comparator接口是,需要在new集合時添加自定義的比較器,
  1.  
    public class TreeSetDome {
  2.  
     
  3.  
    public static void main(String[] args) {
  4.  
    <span style= "color:#ff0000;">//TreeSet具有set接口的所有函數(上面的函數)</span>
  5.  
    //在new時可以加入指定的比較器
  6.  
    TreeSet<Object> set= new TreeSet<Object>(new MyComp());
  7.  
    Person p1= new Person("張三",20);
  8.  
    //TreeSet具有其他函數
  9.  
    //返回此 set 中大於等於給定元素的最小元素;如果不存在這樣的元素,則返回 null
  10.  
    set.ceiling(p1);
  11.  
    //返回對此 set 中的元素進行排序的比較器;如果此 set 使用其元素的自然順序,則返回 null。
  12.  
    set.floor(p1);
  13.  
    //返回此 set 中嚴格大於給定元素的最小元素;如果不存在這樣的元素,則返回 null。
  14.  
    set.comparator();
  15.  
    //返回此 set 中當前第一個(最低)元素。
  16.  
    set.first();
  17.  
    //返回此 set 中當前最后一個(最高)元素。
  18.  
    set.last();
  19.  
    //返回此 set 中小於等於給定元素的最大元素;如果不存在這樣的元素,則返回 null。
  20.  
    set.higher(p1);
  21.  
    //返回此 set 中嚴格小於給定元素的最大元素;如果不存在這樣的元素,則返回 null。
  22.  
    set.lower(p1);
  23.  
    //獲取並移除第一個(最低)元素;如果此 set 為空,則返回 null。
  24.  
    set.pollFirst();
  25.  
    //獲取並移除最后一個(最高)元素;如果此 set 為空,則返回 null。
  26.  
    set.pollLast();
  27.  
     
  28.  
    }
  29.  
     
  30.  
     
  31.  
    }
  32.  
    class MyComp implements Comparator<Object>{
  33.  
     
  34.  
    @Override
  35.  
    public int compare(Object o1, Object o2) {
  36.  
    //返回值為負整數,0,正整數(int型)
  37.  
    //表示本對象比參數對象小,相等,大
  38.  
    return 1;
  39.  
    }
  40.  
    }
List接口

List接口繼承了Collection接口以定義一個允許重復項的有序集合。該接口不但能夠對列表的一部分進行處理,還添加了面向位置的操作。面向位置的操作包括插入某個元素或Collection的功能,還包括獲取、除去或更改元素的功能。在List中搜索元素可以從列表的頭部或尾部開始,如果找到元素,還將報告元素所在的位置。

1)使用List(如ArrayList)時,不會自動調用hashCode()方法。因為在List中,重復了就重復了,不需判斷,保證唯一性。

2)List中添加了下標index的功能,這樣對List的修改可以利用set方法對指定位置的元素直接進行替換,不需要象Set那么復雜(要轉換成數組才能修改,之后還要轉換回去)。

3)Collection用Iterator迭代器,而List可以用ListIterator列表迭代器。前者只能next(),后者不但包含next()方法,還包含previous()方法。因此,如果要用List做類似書的翻頁功能,不但可以向后翻,還可以向前翻。

  1.  
    package cn.hncu.collection;
  2.  
     
  3.  
    import java.util.ArrayList;
  4.  
    import java.util.Iterator;
  5.  
    import java.util.ListIterator;
  6.  
     
  7.  
    public class ArrayListDome {
  8.  
     
  9.  
    public static void main(String[] args) {
  10.  
    //List接口引入了下標,並且可以添加重復的元素
  11.  
    ArrayList<Object> al1= new ArrayList<Object>(0);
  12.  
    ArrayList<Object> al2= new ArrayList<Object>(0);
  13.  
    Person p1= new Person("張三",20);
  14.  
    Person p2= new Person("李四",22);
  15.  
    Person p3= new Person("王五",24);
  16.  
    Person p4= new Person("Jack",30);
  17.  
    Person p5= new Person("Tom",20);
  18.  
    Person p6= new Person("Swite",13);
  19.  
    Person p7= new Person("Pick",16);
  20.  
    Person p8= new Person("錢七",32);
  21.  
    //添加時,根據下標位置排序,無需實現元素的hashCode和equals方法
  22.  
    //可以指定下標添加,但要注意,不能加入的下標大小比集合容量大,否則出異常
  23.  
    al1.add(p1);
  24.  
    al1.add( 0,p2);
  25.  
    al1.add(al1.size()- 1,p3);
  26.  
    al1.add(p4);
  27.  
    al1.add(p5);
  28.  
    al1.add( 0,p6);
  29.  
    al2.add(p2);
  30.  
    al2.add(p4);
  31.  
    al2.add(p6);
  32.  
    al2.add(p8);
  33.  
     
  34.  
    //可以添加其他集合的指定位置
  35.  
    al1.addAll( 0, al2);
  36.  
    //返回此列表中指定位置上的元素。
  37.  
    al1.get( 0);
  38.  
    //返回此列表中首次出現的指定元素的索引,或如果此列表不包含元素,則返回 -1。
  39.  
    al1.indexOf(p1);
  40.  
    //返回此列表中最后一次出現的指定元素的索引,或如果此列表不包含索引,則返回 -1。
  41.  
    al1.lastIndexOf(p1);
  42.  
    //移除此列表中指定位置上的元素。
  43.  
    al1.remove( 0);
  44.  
    //用指定的元素替代此列表中指定位置上的元素。
  45.  
    al1.set( 0, p2);
  46.  
    //按適當順序(從第一個到最后一個元素)返回包含此列表中所有元素的數組。
  47.  
    al1.toArray();
  48.  
    //按適當順序(從第一個到最后一個元素)返回包含此列表中所有元素的數組;返回數組的運行時類型是指定數組的運行時類型。
  49.  
    Person[] a = new Person[0];
  50.  
    a=al1.toArray(a);
  51.  
    //將此 ArrayList 實例的容量調整為列表的當前大小。
  52.  
    al1.trimToSize();
  53.  
    //返回列表中索引在 fromIndex(包括)和 toIndex(不包括)之間的所有元素組成一個新的集合列表。
  54.  
    al1.subList( 0, 1);
  55.  
     
  56.  
     
  57.  
     
  58.  
    //返回此 ArrayList 實例的淺表副本。只是復制了指針,倆個集合共用元素
  59.  
    ArrayList<Object> po=(ArrayList<Object>) al1.clone();
  60.  
    ((Person)al1.get( 0)).age=10000;
  61.  
    ((Person)al2.get( 0)).age=-300;
  62.  
    for (int i = 0; i < po.size(); i++) {
  63.  
    System.out.println(po.get(i));
  64.  
    }
  65.  
    //返回列表的迭代器
  66.  
    ListIterator it=al1.listIterator();
  67.  
    while(it.hasNext()){
  68.  
    System.out.println(it.next()); //當前的下一個
  69.  
    System.out.println(it.previous()); //當前的上一個
  70.  
    }
  71.  
     
  72.  
    }
  73.  
     
  74.  
    }
LickedList

如果要支持隨機訪問,而不必在除尾部的任何位置插入或除去元素,那么,ArrayList提供了可選的集合。(查找)

但如果要頻繁的從列表的中間位置添加和除去元素,而只要順序的訪問列表元素,那么LinkedList實現更好(添加,刪除)
  1.  
    //構造空的
  2.  
    LinkedList list= new LinkedList();
  3.  
     
  4.  
    Person p1= new Person("張三",20);
  5.  
     
  6.  
    <span style= "color:#ff0000;">//鏈表也具有排序和下標功能,ArrayList的函數</span>
  7.  
    //將指定元素插入此列表的開頭。
  8.  
    list.addFirst(p1);
  9.  
    list.offerFirst(p1);
  10.  
    //將指定元素添加到此列表的結尾。
  11.  
    list.addLast(p1);
  12.  
    list.offer(p1);
  13.  
    list.offerLast(p1);
  14.  
    // 獲取但不移除此列表的頭(第一個元素)。
  15.  
    list.element();
  16.  
    list.get( 0);
  17.  
    list.getFirst();
  18.  
    list.peek();
  19.  
    list.peekFirst(); //沒有返回空
  20.  
    //獲取並移除此列表的頭(第一個元素)
  21.  
    list.pop();
  22.  
    list.pollFirst(); //沒有返回空
  23.  
    list.remove( 0);
  24.  
    list.removeFirst();
  25.  
    //移 不移除列表的尾而獲得同頭部;
  26.  
    list.peekLast();
  27.  
    list.getLast();
  28.  
     
  29.  
    list.pollLast();
  30.  
    list.removeLast();
  31.  
    //從此列表中移除第一次出現的指定元素(從頭部到尾部遍歷列表時)。
  32.  
    list.removeFirstOccurrence(p1);
  33.  
    //從此列表中移除最后一次出現的指定元素(從頭部到尾部遍歷列表時)。
  34.  
    list.removeLastOccurrence(p1);
利用ArrayList和LinkedList做隊列和棧
  1.  
    ArrayList<Object> al= new ArrayList<Object>(0);
  2.  
     
  3.  
    public void push(Object obj){
  4.  
    al.add(obj);
  5.  
    }
  6.  
    public Object pop(){
  7.  
    if(!al.isEmpty())
  8.  
    return al.remove(0);
  9.  
    return null;
  10.  
    }
  11.  
     
  12.  
    public boolean isEmpty(){
  13.  
    return al.isEmpty();
  14.  
    }

  1.  
    ArrayList<Object> al= new ArrayList<Object>(0);
  2.  
     
  3.  
    public void push(Object obj){
  4.  
    al.add(obj);
  5.  
    }
  6.  
    public Object pop(){
  7.  
    if(!al.isEmpty())
  8.  
    return al.remove(al.size()-1);
  9.  
    return null;
  10.  
    }
  11.  
     
  12.  
    public boolean isEmpty(){
  13.  
    return al.isEmpty();
  14.  
    }

  1.  
    LinkedList<Object> lkl= new LinkedList<Object>();
  2.  
     
  3.  
    public void push(Object obj){
  4.  
    lkl.add(obj);
  5.  
    }
  6.  
    public Object pop(){
  7.  
    return lkl.poll();
  8.  
    }
  9.  
     
  10.  
    public boolean isEmpty(){
  11.  
    return lkl.isEmpty();
  12.  
    }

  1.  
    LinkedList<Object> lkl= new LinkedList<Object>();
  2.  
     
  3.  
    public void push(Object obj){
  4.  
    lkl.add(obj);
  5.  
    }
  6.  
    public Object pop(){
  7.  
    return lkl.pollLast();
  8.  
    }
  9.  
     
  10.  
    public boolean isEmpty(){
  11.  
    return lkl.isEmpty();
  12.  
    }
Map集合
Map接口不是Collection接口的繼承。而是從自己的用於維護鍵-值關聯的接口層次結構入手。按定義,該接口描述了 從不重復的鍵到值的映射。

可以把這個接口方法分成三組操作:改變、查詢和提供可選視圖。

改變操作允許從映射中添加和除去鍵-值對。鍵和值都可以為null。但是,不能把Map作為一個鍵或值添加給自身

  1.  
    HashMap<String, Object> map= new HashMap<String, Object>(0);
  2.  
    Person p1= new Person("張三",20);
  3.  
    Person p2= new Person("李四",22);
  4.  
    Person p3= new Person("王五",24);
  5.  
    Person p4= new Person("Jack",30);
  6.  
    Person p5= new Person("Tom",20);
  7.  
    Person p6= new Person("Swite",13);
  8.  
     
  9.  
    //鍵-值添加,put函數
  10.  
    map.put( "1001", p1);
  11.  
    map.put( "1002", p2);
  12.  
    map.put( "1003", p3);
  13.  
    map.put( "1004", p4);
  14.  
    map.put( "1005", p5);
  15.  
    map.put( "1006", p6);
  16.  
    //返回指定鍵所映射的值;如果對於該鍵來說,此映射不包含任何映射關系,則返回 null。
  17.  
    map.get( "1001");
  18.  
    //從此映射中移除指定鍵的映射關系(如果存在)。
  19.  
    map.remove( "1001");
  20.  
    //移除集合
  21.  
    map.clear();
  22.  
    //entry視圖
  23.  
    Set<Map.Entry<String, Object>> entry=map.entrySet();
  24.  
    Iterator<Map.Entry<String, Object>> it=entry.iterator();
  25.  
    while(it.hasNext()){
  26.  
    Map.Entry<String, Object> en=it.next();
  27.  
    System.out.println(en.getKey()+ " "+en.getValue());
  28.  
    }
  29.  
    System.out.println( "------------------");
  30.  
    //key視圖
  31.  
    Set<String> keys=map.keySet();
  32.  
    Iterator<String> it2=keys.iterator();
  33.  
    while(it2.hasNext()){
  34.  
    String str=it2.next();
  35.  
    System.out.println(str+ " "+map.get(str));
  36.  
    }
  37.  
    System.out.println( "------------------");
  38.  
    //values視圖(不常用)
  39.  
    Collection<Object> values=map.values();
  40.  
    Iterator<Object> it3=values.iterator();
  41.  
    while(it3.hasNext()){
  42.  
    Object obj=it3.next();
  43.  
    System.out.println(obj);
  44.  
    }
TreeMap
與TreeSet一樣,具有排序功能,且排序要求一樣。

“集合框架”提供兩種常規的Map實現:HashMap和TreeMap。和所有的具體實現一樣,使用哪種實現取決於特定需要。

在Map中插入、刪除和定位元素,HashMap是最好的選擇。但如果要按順序遍歷鍵,那么TreeMap會更好。

使用HashMap要求添加的鍵類明確定義了hashCode()實現(助理解:Map.keySet返回的是鍵的Set集合,而Set集合對hashCode實現有限制,因此作為鍵的類也要遵守該限制)。有了TreeMap實現,添加到映射的元素一定是可排序的

中文排序問題

比較函數對於英文字母與數字等ASCII碼中的字符排序都沒問題,但中文排序則明顯不正確。這主要是Java中使用中文編碼GB2312或GBK時,char型轉換成int型的過程出現了比較大的偏差。這偏差是由compare方法導致的,因此我們可以自己實現Comparator接口。另外,國際化問題可用Collator類來解決。

java.text.Collator類,提供以與自然語言無關的方式來處理文本、日期、數字和消息的類和接口。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM