Java基礎之Collections框架List接口及其源碼分析

Java基礎之Collections框架List接口及其源碼分析


有序集合(也稱爲序列)。 用戶可以精確控制列表中每個元素的插入位置。 用戶可以通過其整數索引(列表中的位置)訪問元素,並在列表中搜索元素。
與集合不同,列表通常允許重複的元素。 更正式地說,列表通常允許成對的元素e1和e2,使得e1.equals(e2),並且如果它們完全允許空元素,則它們通常允許多個空元素。
List接口在Iterator的協定,add,remove,equals和hashCode方法的協定上放置了除Collection接口中指定的規定以外的其他規定。 爲了方便起見,還包含其他繼承方法的聲明。
List接口提供了四種位置(索引)訪問列表元素的方法。 列表(如Java數組)從零開始。 請注意,對於某些實現(例如LinkedList類),這些操作可能在時間上與索引值成比例執行。 因此,如果調用者不知道實現,則遍歷列表中的元素通常比對其進行索引更可取。
List接口提供了一個稱爲ListIterator的特殊迭代器,除了Iterator接口提供的常規操作之外,該迭代器還允許元素插入和替換以及雙向訪問。 提供一種獲取列表迭代器的方法,該列表迭代器從列表中的指定位置開始。
List接口提供了兩種搜索指定對象的方法。 從性能的角度來看,應謹慎使用這些方法。 在許多實現中,它們將執行昂貴的線性搜索。
List接口提供了兩種方法,可以有效地在列表中的任意點插入和刪除多個元素。
注意:雖然允許列表將自身包含爲元素,但建議格外小心:equals和hashCode方法在這樣的列表上不再定義良好。

List接口的特點

索引訪問

根據元素在列表中的數字位置操作元素。 這包括諸如get,set,add,addAll和remove之類的方法。
//獲取元素  索引從0開始
int index = 0;
list.get(index);

搜索

在列表中搜索指定的對象並返回其數字位置。 搜索方法包括indexOf和lastIndexOf。
String index= “tony”;
list.indexOf(index); //獲取tony元素的下標

迭代

擴展Iterator語義以利用列表的順序性質。 ListIterator方法提供了此行爲。
public int indexOf(E e) {
    for (ListIterator<E> it = listIterator(); it.hasNext(); )
        if (e == null ? it.next() == null : e.equals(it.next()))
            return it.previousIndex();
    // Element not found
    return -1;
}

範圍視圖

子列表方法對列表執行任意範圍操作。
int fromIndex = 1,toIndex = 5;
list.subList(fromIndex, toIndex)

Java平臺包含兩個通用的List實現。ArrayList通常是性能更好的實現,而LinkedList在某些情況下性能更好。像Set接口一樣,List增強了對equals和hashCode方法的要求,因此可以比較兩個List對象的邏輯相等性,而不必考慮它們的實現類。 如果兩個List對象包含相同順序的相同元素,則它們相等。

List簡單實例

交換list中指定位置的值
//i和j是list中要替換元素的下標
public static <String> void swap(List<String> a, int i, int j) {
    String tmp = a.get(i);
    a.set(i, a.get(j));
    a.set(j, tmp);
}
//將list中的元素打亂
public static void shuffle(List<String> list, Random rnd) {
    for (int i = list.size(); i > 1; i--)
        swap(list, i - 1, rnd.nextInt(i));
}
public static void main(String[] args) {
   if (args.length < 2) {
        return;
    }
    int numHands = Integer.parseInt(args[0]);
    int cardsPerHand = Integer.parseInt(args[1]);

   String[] suit = new String[] {
       "spades", "hearts", 
       "diamonds", "clubs" 
   };
    String[] rank = new String[] {
        "ace", "2", "3", "4",
        "5", "6", "7", "8", "9", "10", 
        "jack", "queen", "king" 
    };

    List<String> deck = new ArrayList<String>();
    for (int i = 0; i < suit.length; i++)
        for (int j = 0; j < rank.length; j++)
            deck.add(rank[j] + " of " + suit[i]);
	//Collections集合處理類
    Collections.shuffle(deck);

    if (numHands * cardsPerHand > deck.size()) {
        System.out.println("Not enough cards.");
        return;
    }

    for (int i = 0; i < numHands; i++)
        System.out.println(dealHand(deck, cardsPerHand));
}

public static <E> List<E> dealHand(List<E> deck, int n) {
    int deckSize = deck.size();
    List<E> handView = deck.subList(deckSize - n, deckSize);
    List<E> hand = new ArrayList<E>(handView);
    handView.clear();
    return hand;
}

List源碼分析

public interface List<E> extends Collection<E> {
    /**
     返回list中的元素個數
     */
    int size();
    /**
   判斷list是否爲空
     */
    boolean isEmpty();
    /**
    返回list是否包含指定的元素
     */
    boolean contains(Object o);
    /**
   	返回迭代器
     */
    Iterator<E> iterator();
    /**
    	將list轉換爲數組
     */
    Object[] toArray();

    /**
   返回指定類型的數組
     */
    <T> T[] toArray(T[] a);
    /**
     添加元素
     */
    boolean add(E e);

    /**
    移除元素
     */
    boolean remove(Object o);
    /**
     是否包含指定集合中的所有元素
     */
    boolean containsAll(Collection<?> c);

    /**
     添加指定集合中的所有元素到list中
     */
    boolean addAll(Collection<? extends E> c);

    /**
    在指定的位置將指定集合中的元素添加到list中
     */
    boolean addAll(int index, Collection<? extends E> c);
    /**
     移除指定集合中在list中的所有元素
     */
    boolean removeAll(Collection<?> c);

    /**
     removeAll取反
     */
    boolean retainAll(Collection<?> c);

    /**
	用將該運算符應用於該元素的結果替換此列表中的每個元素。
     */
    default void replaceAll(UnaryOperator<E> operator) {
        Objects.requireNonNull(operator);
        //通過迭代器遍歷替換 同時operator獲取元素
        final ListIterator<E> li = this.listIterator();
        while (li.hasNext()) {
            li.set(operator.apply(li.next()));
        }
    }

    /**
     
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    default void sort(Comparator<? super E> c) {
        Object[] a = this.toArray();
        //將list轉爲數組,通過Arrays的sort方法進行排序
        Arrays.sort(a, (Comparator) c);
        //進行迭代器進行迭代設置值達到排序
        ListIterator<E> i = this.listIterator();
        for (Object e : a) {
            i.next();
            i.set((E) e);
        }
    }

    /**
    清除list中的所有元素
     */
    void clear();
    /**
   比較list是否相等 
   個數和包含的元素
     */
    boolean equals(Object o);
    /**
    返回list的hash值,將list中的每一個元素的hashCode進行相加
     */
    int hashCode();
    /**
    獲取指定位置的元素
     */
    E get(int index);

    /**
    給指定的索引設置值
     */
    E set(int index, E element);

    /**
    向指定的位置添加一個元素
     */
    void add(int index, E element);

    /**
     移除指定索引下的元素
     */
    E remove(int index);
    /**
    返回元素的list中的索引
     */
    int indexOf(Object o);

    /**
     返回相關元素最後出現的索引值
     */
    int lastIndexOf(Object o);

    /**
    返回list特殊的List迭代器
     */
    ListIterator<E> listIterator();

    /**
     返回此列表中元素的列表迭代器(正確序列),從列表中的指定位置開始。
     */
    ListIterator<E> listIterator(int index);
    /**
    返回指定位置之間此列表部分的視圖 fromIndex (含)和toIndex(不包含)
    如果相等將返回一個空的list
     返回的列表由該列表支持,因此是非結構化的返回列表中的更改會反映在此			     列表中,反之亦然。返回的列表支持所有支持的可選列表操作通過此列表
     */
    List<E> subList(int fromIndex, int toIndex);

    /**
    返回一個Spliterator實例
     */
    @Override
    default Spliterator<E> spliterator() {
        return Spliterators.spliterator(this, Spliterator.ORDERED);
    }
}

相關的方法的實現是通過List的兩個實現類ArrayListLinkedList去實現的。默認方法 relaceAllsort是jdk 8中支持的語法。這個是在List接口中實現。裏面涉及了Collections類和Arrays類,這個可以認爲是集合操作的相關工具類。到時候研究,哈哈!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章