天天看點

黑馬程式員——集合架構(單列集合:Collection接口)



------- android教育訓練、java教育訓練、期待與您交流! ----------

黑馬程式員——集合架構(單列集合:Collection接口)

 單列集合體系結構圖

 注:圖中列出了程式中常用的單列集合類,其中,虛線框裡都是接口類型,而實線框裡是具體的實作類。

為什麼出現集合類?

面向對象語言對事物的展現都是以對象的形式,是以為了友善對多個對象操作,就對對象進行存儲,集合就是存儲對象常用的一種方式。而每一個容器對資料的存儲方式都有不同,這種存儲資料的方式稱之為資料結構。

數組和集合類同時容器,有何不同?

        數組雖然也可以存儲對象,但長度是固定的,集合的長度是可變的;數組中可以存儲基本資料類型,集合隻能存儲對象。

集合類的特點:

        集合隻用于存儲對象,集合長度是可變的,集合可以存儲不同類型的對象。

一、Collection接口

Collection接口的常用方法:

boolean add(Object o)

         向集合中添加一個元素

boolean addAll(Collection c)

         将指定Collection中的所有元素添加到該集合中

void clear()

         删除該集合中的所有元素

boolean remove(Object o)

         删除該集合中的指定元素

boolean removeAll(Collection c)

         删除指定集合中的所有元素

boolean isEmpty()

         判斷該集合是否為空

boolean contains(Object o)

         判斷該集合中是否包含某個元素

boolean containsAll(Collection c)

         判斷該集合中是否包含指定集合中的所有元素

Iterator iterator()

         傳回在該集合的元素上進行疊代的疊代器(Iterator),用于周遊該集合的所有元素

int size()

         擷取該集合的元素個數

示範:

import java.util.*;

class CollectionDemo

{

   public staticvoid main(String[] args)

   {  }

publicstatic void sop(Object obj)

   {

      System.out.println(obj);

   }

   public staticvoid base_method()

   {

       //建立一個集合容器,使用Collection接口的子類ArrayList

       ArrayListal = new ArrayList();

       //添加元素

       al.add("java01");//add(Objectobj);

       al.add("java02");

       al.add("java03");

       al.add("java04");

       //列印集合

       sop("列印原集合:"+al);

       //删除元素。

       //al.remove("java02");

       //清空集合

       //al.clear();

       //判斷元素

       sop("java03是否存在:"+al.contains("java03"));

       //擷取個數,集合長度

        sop("size:"+al.size());

        sop(al);

    }

public static void method_2()

   {

       ArrayListal1 = new ArrayList();

       al1.add("java01");

       al1.add("java02");

       al1.add("java03");

       al1.add("java04");

       ArrayListal2 = new ArrayList();

       al2.add("java01");

       al2.add("java02");

       al2.add("java05");

       al2.add("java06");

       //al1.retainAll(al2);//取交集,al1中隻會保留和al2中相同的元素。

       al1.removeAll(al2);//移除al1中和al2中相同的元素。    

       sop("al1:"+al1);

       sop("al2:"+al2);

   }

   public staticvoid method_get()

   {

       //添加元素

       al.add("java01");//add(Objectobj);

       al.add("java02");

       al.add("java03");

       al.add("java04");

       //節省記憶體,更優化。

       for(Iteratorit = al.iterator(); it.hasNext(); )

       {

           sop(it.next());

       }

   }  

}

Iterator(疊代器)

每個集合都要取出元素,就把取出方式定義在集合的内部,這樣取出方式就可以直接通路集合内容的元素。那麼取出方式就被定義成了内部類。而每一個容器的資料結構不同,是以取出的動作細節也不一樣。但是都有共性内容:判斷和取出,那麼就可以将其共性抽取(形成Iterator接口)那麼這些内部類都符合一個規則。規則是Iterator。

如何擷取集合的取出對象呢?通過一個對外提供的方法iterator();。

二、List接口

List:元素是有序的,元素可以重複,因為該集合體系有索引。

         ArrayList:底層的資料結構是數組結構,特點:查詢速度快,增删稍慢,線程不同步。

         LinkedList:底層的資料結構是連結清單資料結構,特點:增删速度快,查詢稍慢。

         Vector:底層資料結構是數組,線程同步,被ArrayList代替了。

List接口的常用方法:

void add(int index,Object element)

         将元素element插入在List集合的index處

boolean addAll(int index,Collection c)

         将集合c所包含的所有元素插入到List集合的index處

Object get(int index)

         傳回集合索引index處的元素

Object remove(int index)

         删除index索引處的元素

Object set(int index,Object element)

         将索引index處元素替換成element對象,并将替換後的元素傳回

int indexOf(Object o)

         傳回對象o在List集合中出現的位置索引

int lastIndex(Object o)

         傳回對象o在List集合中最後一次出現的位置索引

List subList(int fromIndex,int toIndex)

         傳回從索引fromIndex(包括)到toIndex(不包括)處所有元素集合組成的子集合。

案例:

import java.util.*;

class ListDemo

{

   public staticvoid sop(Object obj)

   {

       System.out.println(obj);

   }

   public staticvoid method()

   {

       ArrayListal = new ArrayList();

       //添加元素

       al.add("java01");

       al.add("java02");

       al.add("java03");

       sop("原集合是:"+al);

       //在角标1位置添加元素。

       al.add(1,"java09");

       //删除指定位置的元素

       //al.remove(2);

       //修改元素

       //al.set(2,"java007");

       //通過角标擷取元素

       sop("get(1):"+al.get(1));

       sop(al);

       //擷取所有元素

       for(intx=0; x<al.size(); x++)

       {

           sop("al("+x+")="+al.get(x));

       }

       //疊代器擷取

       for(Iteratorit = al.iterator(); it.hasNext(); )

       {

           sop("next:"+it.next());

       }

       //通過indexOf擷取對象的位置。

       sop("index="+al.indexOf("java02"));

       List sub= al.subList(1,3);

       sop("sub="+sub);

   }

   public staticvoid main(String[] args)

   {

       //示範清單疊代器

       ArrayListal = new ArrayList();

       //添加元素

       al.add("java01");

       al.add("java02");

       al.add("java03");

       sop(al);

       ListIteratorli = al.listIterator();

       sop("hasNext():"+li.hasNext());

       while(li.hasNext())

       {

           Objectobj = li.next();

           if(obj.equals("java02"))

               //li.add("java009");

               li.set("java006");

       }

       while(li.hasPrevious())

       {

           sop("pre:"+li.previous());

       }

       sop("hasNext():"+li.hasNext());

       sop("hasPrevious():"+li.hasPrevious());

       sop(al);

   }

}

ListIterator:

List集合特有的疊代器,ListIterator是Iterator的子接口。在疊代時,不可以通過集合對象的方法操作集合中的元素。因為會發生ConcurrentModificationException異常。是以,在疊代時,隻能用疊代器的方法操作元素,可是Iterator方法是有限的,隻能對元素進行判斷,取出,删除的操作,如果想要其他的操作,如:添加,修改等,就需要使用其子接口,ListIterator。該接口中能通過List集合的ListIterator方法擷取。

LinkedList特有方法:

addFirst();//在第一個位置上添加元素

addLast();//在最後一個位置上添加元素

getFirst();//擷取第一個元素

getLast();//擷取最後一個元素

擷取元素,但不删除元素。如果集合中沒有元素,會抛出NoSuchElementException異常

removeFirst();//擷取删除第一個元素

removeLast();//擷取删除最後一個元素

擷取元素,但是元素被删除,如果集合中沒有元素,擷取元素,但不删除元素。如果集合中沒有元素,會抛出NoSuchElementException異常

在JDK1.6出現了替代方法

offerFirst();

offerLast();

添加

peekFirst();

peekLast();

擷取元素,但不删除元素。如果集合中沒有元素,則傳回null

pollFirst();

pollLast();

擷取元素,但是元素被删除。如果集合中沒有元素,則傳回null

*/

例子:

import java.util.*;

class LinkedListDemo

{

   public static void sop(Objectobj)

   {

        System.out.println(obj);

    }

    public static void main(String[]args)

   {

       LinkedList link = new LinkedList();

       link.addLast("java01");

       link.addLast("java02");

       link.addLast("java03");

       link.addLast("java04");

       while(!link.isEmpty())

       {

           sop(link.removeLast());

       }

   }

}

枚舉:

        JDK中提供了一個Vector集合,用法與ArrayList完全相同,差別在于Vector集合是線程安全的,而ArrayList集合是線程不安全的。在Vector類中提供了一個element()方法用于傳回Enumeration對象,通過Enumeration對象就可以周遊集合中的元素。

         其實枚舉和疊代器是一樣的,因為名稱過長以及方法名過長,是以被疊代器取代了。

import java.util.*;

public class VectorDemo

{

         publicstatic void main(String[] args)

{

                  Vectorv = new Vector();/                    //建立Vector對象

                  v.add(“Jack”);                             //向Vector對象中添加元素

                  v.add(“Rose”);                             

                  v.add(“Tom”);

                  Enumerationen = v.elements();               //獲得Enumeration對象

                  while(en.hasMoreElement())                 //判斷該對象是否有更多元素

                  {

                           Objectobj = en.nextElement();           //取出該對象的下一個元素

                           System.out.println(obj);

}

}

}

三、Set集合

|--Set:元素是無序的(存入和取出的順序不一定一緻),元素不可以重複。

    |--HashSet:底層資料結構是哈希表。

        HashSet是如何保證元素唯一性的呢?

        是通過元素的兩個方法,hashCode和equals來完成的,如果元素的HashCode值相同,才會判斷equals

是否為true。如果元素的HashCode值不同,不會調用equals。

        注意,對于判斷元素是否存在,以及删除等操作,依賴的方法是元素的HashCode和equals方法。

    |--TreeSet:可以對Set集合中的元素進行排序。底層資料結構是二叉樹。

保證元素唯一性的依據compareTo方法return 0

        TreeSet排序的第一種方式:

讓元素自身具備比較性。元素需要實作Comparable接口,覆寫compareTo方法。

        這種方式也稱為2元素的自然順序,或者叫做預設順序。

        TreeSet的第二種排序方式:

        當元素自身不具備比較性時,或者具備的比較性不是所需要的。這是需要讓集合自身具備比較性。

在集合初始化時,就有了比較方式。

Set集合的功能和Collection是一緻的。

需求:

往TreeSet集合中存儲自定義對象學生,

想按照學生的年齡進行排序。

記住:

排序時,當主要條件相同時,一定要判斷一下次要條件。

*/

class TreeSetDemo

{

    public staticvoid main(String[] args)

    {

        TreeSetts = new TreeSet();

        //TreeSet集合能排序,但是它不知道按什麼排序,學生對象不具備比較性,

        //在存儲時就會出錯,必須要讓元素具備比較性,怎麼具備比較性呢?

        //實作Comparable接口,重寫compareTo方法(比較對象與指定對象順序)

        ts.add(new Student("lisi02",22));

        ts.add(new Student("lisi007",20));

        ts.add(newStudent("lisi09",19));

                                         //年齡相同,按姓名排序

        ts.add(newStudent("lisi08",19));

        //ts.add(newStudent("lisi007",20));//重複元素存不進來。

        Iteratorit = ts.iterator();

        while(it.hasNext())

        {

            Studentstu = (Student)it.next();

            System.out.println(stu.getName()+"..."+stu.getAge());

        }      

    }

}

class Student implements Comparable//該接口強制讓學生具備比較性。

{

    privateString name;

    private intage;

    Student(Stringname,int age)

    {

        this.name= name;

        this.age= age;

    }

    public intcompareTo(Object obj)//覆寫Comparable中compareTo方法。

    {

        if(!(objinstanceof Student))//判斷obj對象是否屬于Student

            throw new RuntimeException("不是學生對象");//不屬于學生對象抛出異常,此異常不能再方法上聲明,因為是覆寫的方法。

        Student s = (Student)obj;

        System.out.println(this.name+"...compareTo..."+s.name);

        //正整數、零或負整數,根據此對象是大于、等于還是小于指定對象。

        if(this.age>s.age)

            return1;

        if(this.age==s.age)//判斷完年齡(主要條件相同),再判斷姓名(次要條件)

            returnthis.name.compareTo(s.name);//字元串具備比較性,String類本身就實作了Comparable接口

        return-1;

    }

    public StringgetName()

    {

        returnname;

    }

    public intgetAge()

    {

        returnage;

    }

}

importjava.util.*;

class Student implements Comparable//該接口強制讓學生具備比較性。

{

    private String name;

    private int age;

    Student(String name,int age)

    {

        this.name = name;

        this.age = age;

    }

    public int compareTo(Objectobj)//覆寫Comparable中compareTo方法。

    {

        if(!(obj instanceofStudent))//判斷obj對象是否屬于Student

            throw newRuntimeException("不是學生對象");//不屬于學生對象抛出異常,此異常不能再方法上聲明,因為是覆寫的方法。

        Student s = (Student)obj;

        System.out.println(this.name+"...compareTo..."+s.name);

        //正整數、零或負整數,根據此對象是大于、等于還是小于指定對象。

        if(this.age>s.age)

            return 1;

        if(this.age==s.age)//判斷完年齡(主要條件相同),再判斷姓名(次要條件)

            return this.name.compareTo(s.name);//字元串具備比較性,String類本身就實作了Comparable接口

        return -1;

    }

    public String getName()

    {

        return name;

    }

    public int getAge()

    {

        return age;

    }

}

class  TreeSetDemo2

{

    public static void main(String[]args)

    {

        TreeSet ts = new TreeSet(newMyCompare());

        //TreeSet集合能排序,但是它不知道按什麼排序,學生對象不具備比較性,

        //在存儲時就會出錯,必須要讓元素具備比較性,怎麼具備比較性呢?

        //實作Comparable接口,重寫compareTo方法(比較對象與指定對象順序)

        ts.add(newStudent("lisi02",22));

        ts.add(newStudent("lisi02",21));

        ts.add(new Student("lisi007",20));

        ts.add(newStudent("lisi09",19));

                                         //年齡相同,按姓名排序

        ts.add(newStudent("lisi08",19));

        //ts.add(newStudent("lisi007",20));//重複元素存不進來。

        Iterator it = ts.iterator();

        while(it.hasNext())

        {

            Student stu =(Student)it.next();

            System.out.println(stu.getName()+"..."+stu.getAge());

        }  

    }

}

//定義一個比較器實作Comparator,覆寫Compare方法

class MyCompare implements Comparator

{

    public int compare(Objecto1,Object o2)

    {

        Student s1 = (Student)o1;

        Student s2 = (Student)o2;

        int num =s1.getName().compareTo(s2.getName());

        if(num==0)

        {

            return newInteger(s1.getAge()).compareTo(new Integer(s2.getAge()));

        }

        returnnum;

    }

}