1. 程式人生 > >java集合框架(一)Collection

java集合框架(一)Collection

       本篇文章轉載自:http://blog.csdn.net/qq_28261343/article/details/52614411

 Java集合框架主要由CollectionMap兩個根介面及其子介面、實現類組成。Java集合也大致可分為SetListMap三種體系,其中Set代表無序、不可重複的集合;List代表有序、可重複的集合;而Map則代表具有對映關係的集合。Java 5之後,增加了Queue體系集合,代表一種佇列集合實現。其中SetListQueue繼承自Collection介面。

本文僅探討Collection介面及其子介面、實現類。

(1)集合和陣列有什麼區別?

1:長度限制之別

  ·陣列長度是固定不變的

  ·集合的大小是可變的

2:可以儲存的型別之別

  ·一個數組儲存的元素可以是基本型別,也可以是引用型別,且只能儲存同一種類型的元素

·一個集合儲存的元素只能是引用型別,但集合可以儲存不同型別的元素(但集合一般儲存同一種類型)

(2)java集合框架初窺


1、Collection之繼承體系

下面列出了常用的Collection集合的繼承關係。

Collection

    |-----List  有序(儲存順序和取出順序一致),可重複

        |----ArrayList ,執行緒不安全,底層使用陣列實現,查詢快,增刪慢。效率高。

                每次容量不足時,自增長度的一半,如下原始碼可知

                  intnewCapacity = oldCapacity + (oldCapacity >> 1);

        |----LinkedList , 執行緒不安全,底層使用連結串列實現,查詢慢,增刪快。效率高

        |----Vector , 執行緒安全,底層使用陣列實現,查詢快,增刪慢。效率低

                每次容量不足時,預設自增長度的一倍(如果不指定增量的話),如下原始碼可知

                   intnewCapacity = oldCapacity + ((capacityIncrement > 0) ?

                                    capacityIncrement : oldCapacity);

    |-----Set   元素唯一

    一個不包含重複元素的collection。更確切地講,set 不包含滿足 e1.equals(e2) 的元素對 e1 和 e2,並且最多包含一個 null 元素。

        |--HashSet 底層是由HashMap實現的,通過物件的hashCode方法與equals方法來保證插入元素的唯一性,無序(儲存順序和取出順序不一致),。

            |--LinkedHashSet 底層資料結構由雜湊表和連結串列組成。雜湊表保證元素的唯一性,連結串列保證元素有序。(儲存和取出是一致)

        |--TreeSet 基於 TreeMap 的NavigableSet 實現。使用元素的自然順序對元素進行排序,或者根據建立 set 時提供的 Comparator 進行排序,具體取決於使用的構造方法。元素唯一。

2、Collection泛型介面

方法摘要

 boolean add(E e)

              確保此collection 包含指定的元素(可選操作)。

     booleanaddAll(Collection<? extends E> c)

              將指定collection 中的所有元素都新增到此 collection 中(可選操作)。

     void clear()

              移除此 collection 中的所有元素(可選操作)。

     boolean contains(Objecto)

              如果此collection 包含指定的元素,則返回 true。

     booleancontainsAll(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中移除指定元素的單個例項,如果存在的話(可選操作)。

     booleanremoveAll(Collection<?> c)

              移除此collection 中那些也包含在指定 collection 中的所有元素(可選操作)。

     booleanretainAll(Collection<?> c)

              僅保留此 collection中那些也包含在指定 collection 的元素(可選操作)。

     int size()

              返回此collection 中的元素數。

     Object[] toArray()

              返回包含此collection 中所有元素的陣列。

    <T> T[]

     toArray(T[] a)

使用Collection示例

public class CollectionReview {

    public static voidmain(String[] args) {

        test1();

    }

    private static voidtest1() {

       Collection<String> collection = new Vector<>();

       collection.add("gogogo");

       collection.add("pap");

       collection.add("niko");

       collection.add("kitty");

       Collection<String> coll = new ArrayList<>();

       coll.add("niko");

       coll.add("kitty");

       coll.add("pecuyu");

        // collection.clear();// 清空集合

        //System.out.println(collection.isEmpty()); // 集合是否為空

        // int size =collection.size(); // 獲取集合大小

        // System.out.println(size); 

        // boolean contains =collection.contains("niko"); // 是否包含另一個元素

        //System.out.println(contains);

        //boolean containsAll= collection.containsAll(coll); //是否完全包含另一個集合

       //System.out.println(containsAll);

        //collection.remove("kitty");  // 刪除第一個匹配項,刪除了匹配項則返回true

        // boolean removeAll =collection.removeAll(coll);  // 刪除與指定集合有交集的部分,原集合有改變就返回true

        //System.out.println(removeAll);

        //boolean retainAll =collection.retainAll(coll);// 保留與指定集合有交集的部分,原集合有改變就返回true

       //System.out.println(retainAll);

    // iterator 迭代器, 方式1

        Iterator<String>iterator = collection.iterator();

       while(iterator.hasNext()){

           System.out.print(iterator.next()+" ");

        }

       System.out.println("\n"+"-------------------");

    // 方式2 ,for迴圈完iterator1就會被銷燬,節約記憶體提高效率

        for(Iterator<String> iterator1 = collection.iterator(); iterator1.hasNext();) {

           System.out.print(iterator1.next()+" ");

        }

        System.out.println("\n"+"-------------------");

        Object[] array =collection.toArray();  // 轉化為object陣列

        for (Object string :array) {

           System.out.print(string+" ");

        }

       System.out.println("\n"+"-------------------");

        String[] arr=newString[collection.size()];

        String[] array2 =collection.toArray(arr);  // 指定要轉化的陣列型別

        for (String string :array2) {

           System.out.print(string+" ");

        }

    }

3、List泛型介面

繼承自Collection

特有方法(相對於Collection)

 void add(int index, Eelement)

          在列表的指定位置插入指定元素(可選操作)。

 boolean addAll(int index,Collection<? extends E> c)

          將指定collection 中的所有元素都插入到列表中的指定位置(可選操作)。 

 E get(int index)

          返回列表中指定位置的元素。 

 int indexOf(Object o)

          返回此列表中第一次出現的指定元素的索引;如果此列表不包含該元素,則返回 -1。 

 int lastIndexOf(Object o)

          返回此列表中最後出現的指定元素的索引;如果列表不包含此元素,則返回 -1。

 ListIterator<E>listIterator()

          返回此列表元素的列表迭代器(按適當順序)。

 ListIterator<E>listIterator(int index)

          返回列表中元素的列表迭代器(按適當順序),從列表的指定位置開始。

 E remove(int index)

          移除列表中指定位置的元素(可選操作)。

 E set(int index, E element)

          用指定元素替換列表中指定位置的元素(可選操作)。

 List<E> subList(intfromIndex, int toIndex)

          返回列表中指定的fromIndex(包括)和 toIndex(不包括)之間的部分檢視。

3.1、ArrayList類

繼承自AbstractList,實現了Iterable,Collection, List,Cloneable, Serializable

每次容量不足時,自增長度的一半

int newCapacity = oldCapacity + (oldCapacity >> 1);

1 構造方法

    ArrayList()

          構造一個初始容量為 10 的空列表(每次遞增容量的一半)

    ArrayList(Collection<?extends E> c)

          構造一個包含指定 collection 的元素的列表,這些元素是按照該 collection 的迭代器返回它們的順序排列的

    ArrayList(intinitialCapacity)

          構造一個具有指定初始容量的空列表

2 特有方法(相對於List)

void ensureCapacity(int minCapacity)

          如有必要,增加此ArrayList 例項的容量,以確保它至少能夠容納最小容量引數所指定的元素數。

          返回此列表中最後一次出現的指定元素的索引,或如果此列表不包含索引,則返回 -1。

 protected  void removeRange(int fromIndex, int toIndex)

          移除列表中索引在fromIndex(包括)和 toIndex(不包括)之間的所有元素。

3 ArrayList使用示例

public class ArrayListReview {

    public static voidmain(String[] args) {

        ArrayList<Info>infosList=new ArrayList<>();

        infosList.add(newInfo(0, "aaa"));

        infosList.add(newInfo(1, "bbb"));

        infosList.add(newInfo(2, "ccc"));

        infosList.add(newInfo(3, "ddd"));

        infosList.add(1, newInfo(4, "eee")); // 按索引插入到指定位置

        // foreach遍歷輸出

        for (Info info :infosList) {

           System.out.println(info);

        }

        System.out.println("------------------------");

        // 擷取字串

        List<Info>subList = infosList.subList(1, 3);

        subList.add(newInfo(30, "fly"));

        printList(subList);

        ArrayList<Info>newInfosList=new ArrayList<>();

        newInfosList.add(newInfo(11, "qqq"));

        newInfosList.add(newInfo(12, "www"));

       ArrayList<String> ss=new ArrayList<>();

//     infosList.addAll(newInfosList); // 新增一個指定集合到原集合最後,注意兩個集合的泛型引數一致

       infosList.addAll(2,newInfosList); // 將指定集合插入到指定位置

       //printList(infosList);

        Info info =infosList.get(2);  // 取出指定位置的元素

       System.out.println(info);

        infosList.set(0, newInfo(10, "rrr"));   // 替換指定索引位置的元素

       //printList(infosList);

        int index =infosList.indexOf(info);  //根據元素獲取元素第一次出現的索引,不存在則返回-1

        int lastIndex =infosList.lastIndexOf(info); // 取出元素的最後一個匹配項的索引

        int indexOf =infosList.indexOf(new Info(4,"eee")); // 重寫了Info類的hashCode與equals方法,用於判斷兩個物件是否相同

       System.out.println("index="+indexOf);

       //printList(infosList);

        // 通過反射拿到的removeRange方法

        removeRange(infosList,1, 3);

       //printList(infosList);

        // listIterator從前往後迭代

       ListIterator<Info> listIterator = infosList.listIterator();

       while(listIterator.hasNext()){

            // 最後丟擲錯誤,java.util.NoSuchElementException,不要每次取都掉用next方法,它每呼叫一次,迭代器指標向前移動一位

//         System.out.println("id="+listIterator.next().getId()

//                 +"adress="+listIterator.next().getAdress());

            Info next =listIterator.next();  // 正確做法,呼叫一次要取出元素,然後操作屬性

           System.out.println("id="+next.getId()

                    +"adress="+next.getAdress());

        }

        // 往前迭代,必須在往後迭代之後用

       while(listIterator.hasPrevious()){ // 當有上一個元素時

            Info previous =listIterator.previous();  // 獲取上一個元素

           System.out.println("id="+previous.getId()+"adresss="+previous.getAdress());

        }

        // 通過陣列來轉化成一個List,雖然可以把陣列轉成集合,但是集合的長度不能改變。

        String[] a=newString[]{"hello","world","just","do","it"};

        List<String>asList = Arrays.asList(a);

       //asList.add("gogogo"); //不可修改asList,會丟擲UnsupportedOperationException

        // 泛型使用

//     ArrayList<Object> l=new ArrayList<String>();// 不行

//     ArrayList<ArrayList> lll=new ArrayList<List>(); // 不行

//      ArrayList<List>lll=new ArrayList<ArrayList>(); // 不行

//      ArrayList l=newArrayList<String>(); // 可行

//     ArrayList<String> l=new ArrayList<>(); // 可行

//      ArrayList ll=newArrayList();  // 可行

    }

    // 列印輸出

    public static <E>void printList(List<E> list) {

        for (E e : list) {

           System.out.println(e);

        }

       System.out.println("------------------------");

    }

}

4 ArrayList的removeRange的使用

removeRange方法是protect訪問許可權,無法直接使用,可以通過反射拿到它

    /**

     * 通過反射呼叫ArrayList的removeRange方法

     * @param list  用於刪除元素的list

     * @param fromIndex 起始刪除索引,包含

     * @param toIndex   結束刪除索引,不包含

     */

    public static <E>void removeRange(ArrayList<E> list,int fromIndex, int toIndex) {

        try {

            // 拿到ArrayList的Class物件

            Class<?>clazz = Class.forName("java.util.ArrayList");

            // 通過clazz物件拿到removeRange方法,引數為(int,int)

            MethoddeclaredMethod = clazz.getDeclaredMethod("removeRange",int.class,int.class);

            // 將方法的訪問許可權設定為可訪問

           declaredMethod.setAccessible(true);

            //  呼叫removeRange方法

           declaredMethod.invoke(list,fromIndex,toIndex); 

        } catch(ClassNotFoundException e) {

           e.printStackTrace();

        }catch(NoSuchMethodException e) {

           e.printStackTrace();

        } catch(SecurityException e) {

           e.printStackTrace();

        } catch (IllegalAccessExceptione) {

           e.printStackTrace();

        } catch(IllegalArgumentException e) {

           e.printStackTrace();

        } catch(InvocationTargetException e) {

           e.printStackTrace();

        }

    }

Info類如下

public class Info   {

    private int id;

    private String adress;

    public Info(int id, Stringadress) {

        super();

        this.id = id;

        this.adress = adress;

    }

    public int getId() {

        return id;

    }

    public void setId(int id){

        this.id = id;

    }

    public String getAdress(){

        return adress;

    }

    public voidsetAdress(String adress) {

        this.adress = adress;

    }

    @Override

    public String toString() {

        return "Info[id=" + id + ", adress=" + adress + "]";

    }

    @Override

    public int hashCode() {

        final int prime = 31;

        int result = 1;

        result = prime *result + ((adress == null) ? 0 : adress.hashCode());

        result = prime *result + id;

        return result;

    }

    @Override

    public booleanequals(Object obj) {

        if (this == obj)

            return true;

        if (obj == null)

            return false;

        if (getClass() !=obj.getClass())

            return false;

        Info other = (Info)obj;

        if (adress == null) {

            if (other.adress!= null)

                return false;

        } else if(!adress.equals(other.adress))

            return false;

        if (id != other.id)

            return false;

        return true;

    }

}

3.2、LinkedList類

繼承自AbstractSequentialList,實現了List,Deque, Cloneable, Serializable

底層使用連結串列實現,查詢慢,增刪快。執行緒不安全,效率高

1 構造方法

 LinkedList()

          構造一個空列表。

 LinkedList(Collection<?extends E> c)

          構造一個包含指定collection 中的元素的列表,這些元素按其 collection 的迭代器返回的順序排列。

2 特有方法(相對於List)

實現了Deque, Queue ,獲得了他們的方法,關係如下

Queue 方法       等效 Deque 方法

add(e)  addLast(e)

offer(e)        offerLast(e)

remove()     removeFirst()

poll()    pollFirst()

element()    getFirst()

peek()  peekFirst()

堆疊方法(Deque作堆疊)    等效 Deque 方法

push(e)         addFirst(e)

pop()    removeFirst()

peek()  peekFirst()

 void addFirst(E e)

          將指定元素插入此列表的開頭。

 void addLast(E e)

          將指定元素新增到此列表的結尾。

 Iterator<E>descendingIterator()

          返回以逆向順序在此雙端佇列的元素上進行迭代的迭代器。

 E element()

          獲取但不移除此列表的頭(第一個元素)。    

 E getFirst()

          返回此列表的第一個元素。

 E getLast()

          返回此列表的最後一個元素。

 boolean offer(E e)

          將指定元素新增到此列表的末尾(最後一個元素)。

 boolean offerFirst(E e)

          在此列表的開頭插入指定的元素。

 boolean offerLast(E e)

          在此列表末尾插入指定的元素。

 E peek()

          獲取但不移除此列表的頭(第一個元素)。

 E peekFirst()

          獲取但不移除此列表的第一個元素;如果此列表為空,則返回 null。

 E peekLast()

          獲取但不移除此列表的最後一個元素;如果此列表為空,則返回 null。

 E poll()

          獲取並移除此列表的頭(第一個元素)

 E pollFirst()

          獲取並移除此列表的第一個元素;如果此列表為空,則返回 null。

 E pollLast()

          獲取並移除此列表的最後一個元素;如果此列表為空,則返回 null。

 E pop()

          從此列表所表示的堆疊處彈出一個元素。

 void push(E e)

          將元素推入此列表所表示的堆疊。

 E removeFirst()

          移除並返回此列表的第一個元素。

 E removeLast()

          移除並返回此列表的最後一個元素。

 booleanremoveFirstOccurrence(Object o)

          從此列表中移除第一次出現的指定元素(從頭部到尾部遍歷列表時)。

 booleanremoveLastOccurrence(Object o)

          從此列表中移除最後一次出現的指定元素(從頭部到尾部遍歷列表時)。

3 LinkedList使用示例

public class LinkListReview {

    public static voidmain(String[] args) {

       LinkedList<String> list=new LinkedList<>();

       list.addFirst("qqq"); // 將指定元素插入此列表的開頭。

       list.addLast("eee");   // 將指定元素新增到此列表的結尾。

       list.addFirst("www"); // 到此list的排序為: www qqqeee

//      list.set(2,"ttt");  // 替換指定位置的元素,注意索引要小於list的size

        Iterator<String>descendingIterator = list.descendingIterator(); // 反向迭代器

        while(descendingIterator.hasNext()) {

           System.out.print(descendingIterator.next()+" ");

        }

       System.out.println("\n"+"-------------------------");

        // ListIterator迭代,指定迭代的起始位置

       ListIterator<String> listIterator = list.listIterator(1); // 正反向都可迭代,反向迭代須在正向之後進行,

       while(listIterator.hasNext()){

           System.out.print(listIterator.next()+" ");

        }

       System.out.println("\n"+"-------------------------");

        // 元素的獲取與新增

        String element =list.element(); // 獲取但不移除此列表的頭(第一個元素)

        System.out.println(element);

        String first =list.getFirst();  // 返回此列表的第一個元素

        String last =list.getLast();   //  返回此列表的最後一個元素

       System.out.println("first="+first+" last="+last);

       System.out.println("peek="+list.peek());//  peek() 獲取但不移除此列表的頭(第一個元素)。

       System.out.println("peekFirst="+list.peekFirst()); //EpeekFirst() 獲取但不移除此列表的第一個元素;如果此列表為空,則返回 null。

       System.out.println("peekLast="+list.peekLast()); ////E peekLast()  獲取但不移除此列表的最後一個元素;如果此列表為空,則返回 null。

        printList(list);

       System.out.println("poll="+list.poll()); // poll()  獲取並移除此列表的頭(第一個元素)

       System.out.println("pollFirst="+list.pollFirst());//EpollFirst() 獲取並移除此列表的第一個元素;如果此列表為空,則返回 null。

       System.out.println("pollLast="+list.pollLast());//EpollLast()  獲取並移除此列表的最後一個元素;如果此列表為空,則返回 null。

        printList(list);

       list.push("push"); //void push(E e)  將元素推入此列表所表示的堆疊,相當於addFirst(Ee)。此方法繼承自Deque

       list.push("push1");

        list.push("push2");

        list.pop(); //E pop() 從此列表所表示的堆疊處彈出一個元素。 若list的集合為空,則丟擲//Epop() 從此列表所表示的堆疊處彈出一個元素。

        printList(list);

       list.offer("offer"); //   將指定元素新增到此列表的末尾(最後一個元素)。

       list.offerFirst("offerFirst"); //在此列表的開頭插入指定的元素。

       list.offerLast("offerLast");   //在此列表末尾插入指定的元素。

        printList(list);

        //removeFirstOccurrence刪除第一個匹配項,removeLastOccurrence刪除最後一個匹配項都是順序遍歷方向

       System.out.println("removeFirstOccurrence="+list.removeFirstOccurrence("offerFirst"));

       System.out.println("removeLastOccurrence="+list.removeLastOccurrence("offerLast"));

        printList(list);

        // 通過集合的方式山刪除要刪除的元素

       LinkedList<String> dyingList=new LinkedList<>();

       for(ListIterator<String> li=list.listIterator();li.hasNext();){

            String next =li.next();

            if(next.equals("push")) {

            //  list.removeFirstOccurrence(next); // 不能再迴圈時修改,丟擲併發修改異常ConcurrentModificationException

                dyingList.add(next);  // 將要刪除的元素儲存起來以備刪除

            }

        }

       list.removeAll(dyingList); // 刪除要移除的元素

        printList(list);

        // ListIterator進行遍歷,並進行修改

       for(ListIterator<String> it=list.listIterator();it.hasNext();){

            String next=it.next();

           if(next.equals("offer")){

            //  it.remove(); // 移除當前,即next所指元素

            //  it.set("newOffer"); // 替換當前,即next所指元素

               it.add("newHere"); // 新增元素,在next所指元素之後

            }

        }

        printList(list);

        // for迴圈通過list進行修改

        for(inti=0;i<list.size();i++){

           if(list.get(i).equals("push1")){

               list.remove(i);

            }

        }

        printList(list);

    }

    public static <E>void printList(List<E> list) {

        for (E e : list) {

           System.out.print(e+" ");

        }

       System.out.println("\n-------------------------");

    }

}

3.3、Vector類

繼承自AbstractList,實現了List,Cloneable, Serializable介面

每次容量不足時,預設自增長度的一倍(如果不指定增量的話)

  int newCapacity =oldCapacity + ((capacityIncrement > 0) ?

                                        capacityIncrement : oldCapacity);

3.31 構造方法摘要

    Vector()

          構造一個空向量,使其內部資料陣列的大小為10,其標準容量增量為零。

    Vector(Collection<?extends E> c)

          構造一個包含指定collection 中的元素的向量,這些元素按其 collection 的迭代器返回元素的順序排列。

    Vector(intinitialCapacity)

          使用指定的初始容量和等於零的容量增量構造一個空向量。

    Vector(intinitialCapacity, int capacityIncrement)

          使用指定的初始容量和容量增量構造一個空的向量。

3.32 特有方法摘要

 void addElement(E obj)

          將指定的元件新增到此向量的末尾,將其大小增加 1。

 void copyInto(Object[]anArray)

          將此向量的元件複製到指定的陣列中。

 E elementAt(int index)

          返回指定索引處的元件。

 Enumeration<E>elements()

          返回此向量的元件的列舉。

 void ensureCapacity(intminCapacity)

          增加此向量的容量(如有必要),以確保其至少能夠儲存最小容量引數指定的元件數。

 E firstElement()

          返回此向量的第一個元件(位於索引 0) 處的項)。

 void insertElementAt(E obj,int index)

          將指定物件作為此向量中的元件插入到指定的 index 處。

 E lastElement()

          返回此向量的最後一個元件。

 void removeAllElements()

          從此向量中移除全部元件,並將其大小設定為零。

 boolean removeElement(Objectobj)

          從此向量中移除變數的第一個(索引最小的)匹配項。

 void removeElementAt(intindex)

          刪除指定索引處的元件。

 protected  void removeRange(int fromIndex, int toIndex)

          從此 List 中移除其索引位於fromIndex(包括)與 toIndex(不包括)之間的所有元素。

 void setElementAt(E obj, intindex)

          將此向量指定 index 處的元件設定為指定的物件。

 void setSize(int newSize)

          設定此向量的大小。

3.33 Vector使用示例

public class VectorReview {

    public static voidmain(String[] args) {

        Vector<String>vector=new Vector<>();

       vector.addElement("e1");

       vector.addElement("e2");

       vector.addElement("e3");

       vector.addElement("e4");

       vector.addElement("e5");

        vector.add(3,"e6");  //在指定位置新增元素,非覆蓋

        printList(vector);

        // copyInto將內容拷貝到一個數組中

        String[] anArray=newString[vector.size()];  // 注意陣列長度不要小於vector的size

       vector.copyInto(anArray);

        for (String string :anArray) {

           System.out.print(string+" ");

        }

       System.out.println("\n--------");

        // 返回指定位置的元素

        String elementAt =vector.elementAt(2);

       System.out.println(elementAt);

       System.out.println(vector.firstElement()); // 返回此向量的第一個元件,索引0的元素

       System.out.println(vector.lastElement()); //返回此向量的最後一個元件

        // 刪除元素

       //vector.removeAllElements(); //  從此向量中移除全部元件,並將其大小設定為零。

       System.out.println(vector.removeElement("e5")); //   從此向量中移除變數的第一個(索引最小的)匹配項。

       vector.removeElementAt(2); //  刪除指定索引處的元件。

       vector.setElementAt("yyy", 3); //   將此向量指定 index 處的元件設定為指定的物件。注意index要小於vector的size

        printList(vector);

        // 返回此向量的元件的列舉

        Enumeration<String>elements = vector.elements();

       while(elements.hasMoreElements()){

           System.out.print(elements.nextElement()+" ");

        }

       System.out.println("\n--------");  

    }

    public static voidprintList(List<String> list) {

        for (String string :list) {

           System.out.print(string+" ");

        }

       System.out.println("\n-----------------");

    }

3.4 併發修改異常

1:出現的現象

    迭代器遍歷集合,集合修改集合元素

2:原因

    迭代器是依賴於集合的,而集合的改變迭代器並不知道。

3:解決方案

    1:迭代器遍歷,迭代器修改(ListIterator)

            元素新增在剛才迭代的位置

    2:集合遍歷(普通for迴圈),集合修改

            元素新增在集合的末尾

    3:遍歷集合,將要刪除的元素新增到另一個集合,然後原集合通過removeAll刪除待刪除的集合

方案3示例

// 通過集合的方式山刪除要刪除的元素

       LinkedList<String> dyingList=new LinkedList<>();

        for(ListIterator<String>li=list.listIterator();li.hasNext();){

            String next =li.next();

            if(next.equals("push")) {

            //  list.removeFirstOccurrence(next); // 不能再迴圈時修改,丟擲併發修改異常ConcurrentModificationException

               dyingList.add(next);  // 將要刪除的元素儲存起來以備刪除

            }

        }

       list.removeAll(dyingList); // 刪除要移除的元素

3.5 Iterator的替代品 -增強for迴圈

(1)for迴圈的一種

(2)書寫格式:

    for(元素的資料型別 變數名 : 陣列或者Collection集合的物件) {

        使用該變數即可,該變數其實就是陣列或者集合中的元素。

    }

(3)好處:

    簡化了陣列和集合的遍歷

(4)弊端

    增強for迴圈的目標不能為null。建議在使用前,先判斷是否為null。

// 增強for

for (String s : array) {

    System.out.println(s);

}

反編譯可知增強是通過Iterator來實現的

for (Iterator iterator = array.iterator(); iterator.hasNext();System.out.println(s))

    s =(String)iterator.next();

4. Set泛型介面

一個不包含重複元素的collection,實現了Collection, Iterable 介面,常見子類 HashSet, LinkedHashSet, TreeSet

方法摘要

 相對於Collection沒有特殊方法,略

4.1 TreeSet

TreeSet 基於 TreeMap 的 NavigableSet 實現。非同步,排序,元素唯一。通過Collections.synchronizedSortedSet 方法來“包裝”該 TreeSet實現同步

必須保證元素可排序性,如下兩種方法

  ① 使用元素的自然順序對元素進行排序(元素要實現Comparable介面並重寫compare方法)。

  ② 根據建立 set 時提供的Comparator 進行排序。

4.11 構造方法摘要

TreeSet()

          構造一個新的空 set,該 set 根據其元素的自然順序進行排序。

 TreeSet(Collection<?extends E> c)

          構造一個包含指定collection 元素的新 TreeSet,它按照其元素的自然順序進行排序。

 TreeSet(Comparator<? superE> comparator)

          構造一個新的空TreeSet,它根據指定比較器進行排序。

 TreeSet(SortedSet<E> s)

          構造一個與指定有序 set具有相同對映關係和相同排序的新 TreeSet。

4.12 特有方法摘要 (相對於Set)

 E ceiling(E e)

          返回此 set 中大於等於給定元素的最小元素;如果不存在這樣的元素,則返回 null。

 Comparator<? super E>comparator()

          返回對此 set 中的元素進行排序的比較器;如果此 set 使用其元素的自然順序,則返回 null。

 Iterator<E>descendingIterator()

          返回在此 set 元素上按降序進行迭代的迭代器。

 NavigableSet<E>descendingSet()

          返回此 set 中所包含元素的逆序檢視。

 E first()

          返回此 set 中當前第一個(最低)元素。

 E floor(E e)

          返回此 set 中小於等於給定元素的最大元素;如果不存在這樣的元素,則返回 null。

 SortedSet<E> headSet(EtoElement)

          返回此 set 的部分檢視,其元素嚴格小於toElement。

 NavigableSet<E>headSet(E toElement, boolean inclusive)

          返回此 set 的部分檢視,其元素小於(或等於,如果 inclusive 為 true)toElement。

 E higher(E e)

          返回此 set 中嚴格大於給定元素的最小元素;如果不存在這樣的元素,則返回 null。

 Iterator<E> iterator()

          返回在此 set 中的元素上按升序進行迭代的迭代器。

 E last()

          返回此 set 中當前最後一個(最高)元素。

 E lower(E e)

          返回此 set 中嚴格小於給定元素的最大元素;如果不存在這樣的元素,則返回 null。

 E pollFirst()