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类,这个可以认为是集合操作的相关工具类。到时候研究,哈哈!

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