zoukankan      html  css  js  c++  java
  • Java List 链表使用及源码分析

    继承关系

    ArrayList

    LinkedList

    源码分析

    由上图,可以看到 ArrayList 和 LinkedList 的继承关系。
    两者都是继承自 AbstractList。那么我们就先分析AbstractList 以及它所继承的类和接口。

    1、由最抽象的 Iterable 开始分析源码。

    //实现这个接口,让目标对象类能支持for-each循环
    public interface Iterable<T> {
       
        //返回迭代器对象
        Iterator<T> iterator();
    
        //默认方法,遍历符合action要求的元素
        default void forEach(Consumer<? super T> action) {
            Objects.requireNonNull(action);
            for (T t : this) {
                action.accept(t);
            }
        }
        
        //默认方法:从当前可迭代类中返回个可拆分的迭代器 Spliterator
        default Spliterator<T> spliterator() {
            return Spliterators.spliteratorUnknownSize(iterator(), 0);
        }
    }
    
    

    具体迭代器用法参考:廖老师的使用Iterator教程

    Iterable 接口有一个返回了 iterator 方法,以及两个Java8才开始支持的默认方法:forEach 和 spliterator
    这个接口代码比较简单,主要是做迭代器相关的操作。

    2、接下来分析 Collection 接口的源码

    点击查看Collection代码
    public interface Collection<E> extends Iterable<E> {
        // Query Operations
    
        int size();
    
        boolean isEmpty();
    
        boolean contains(Object o);
    
        Iterator<E> iterator();
    
        Object[] toArray();
    
        // Modification Operations
    
        boolean add(E e);
    
        boolean remove(Object o);
    
    
        // Bulk Operations
    
        boolean containsAll(Collection<?> c);
    
       
        boolean addAll(Collection<? extends E> c);
    
        boolean removeAll(Collection<?> c);
    
        default boolean removeIf(Predicate<? super E> filter) {
            Objects.requireNonNull(filter);
            boolean removed = false;
            final Iterator<E> each = iterator();
            while (each.hasNext()) {
                if (filter.test(each.next())) {
                    each.remove();
                    removed = true;
                }
            }
            return removed;
        }
    
        boolean retainAll(Collection<?> c);
    
        void clear();
    
    
        // Comparison and hashing
    
       
        boolean equals(Object o);
    
        int hashCode();
    
        @Override
        default Spliterator<E> spliterator() {
            return Spliterators.spliterator(this, 0);
        }
    
        default Stream<E> stream() {
            return StreamSupport.stream(spliterator(), false);
        }
    
        default Stream<E> parallelStream() {
            return StreamSupport.stream(spliterator(), true);
        }
    }
    
    

    源码的注释写得很清晰,Collection接口中的方法主要分为以下几类操作:

    绝大部分方法,我们只看方法名就能够知道是干什么的。单独讲讲 retainAll 方法的作用与使用:

    简单来说,retainAll 方法是用来取两个 Collection 交集的方法。这个方法会修改当前集合对象。

           ArrayList<String> stringList = new ArrayList<>();
            stringList.add("Hello");
            stringList.add("World");
            stringList.add("Java");
    
            ArrayList<String> parameterStrList = new ArrayList<>();
            parameterStrList.add("Python");
            parameterStrList.add("Java");
            parameterStrList.add("Hello");
    
            System.out.println("retain方法执行前:" + stringList);
            stringList.retainAll(parameterStrList);
    
            System.out.println("retain方法执行后:" + stringList);
            System.out.println("retain方法参数:" + parameterStrList);
    
    //retain方法执行前:[Hello, World, Java]
    //retain方法执行后:[Hello, Java]
    //retain方法参数:[Python, Java, Hello]
    
    

    3. List接口源码分析

    public interface List<E> extends Collection<E> {
        // Query Operations
        
        int size();
        boolean isEmpty();
        boolean contains(Object o);
        Iterator<E> iterator();
        Object[] toArray();
        <T> T[] toArray(T[] a);
    
    
        // Modification Operations
        boolean add(E e);
        boolean remove(Object o);
    
    
        // Bulk Modification Operations
        boolean containsAll(Collection<?> c);
        boolean addAll(Collection<? extends E> c);
        boolean addAll(int index, Collection<? extends E> c);
        boolean removeAll(Collection<?> c);
        boolean retainAll(Collection<?> c);
        default void replaceAll(UnaryOperator<E> operator) {
            Objects.requireNonNull(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();
            Arrays.sort(a, (Comparator) c);
            ListIterator<E> i = this.listIterator();
            for (Object e : a) {
                i.next();
                i.set((E) e);
            }
        }
    
        void clear();
    
    
        // Comparison and hashing
        boolean equals(Object o);
        int hashCode();
    
    
        // Positional Access Operations
        E get(int index);
        E set(int index, E element);
        void add(int index, E element);
        E remove(int index);
    
    
        // Search Operations
        int indexOf(Object o);
        int lastIndexOf(Object o);
    
    
        // List Iterators
        ListIterator<E> listIterator();
        ListIterator<E> listIterator(int index);
    
        // View
        List<E> subList(int fromIndex, int toIndex);
        @Override
        default Spliterator<E> spliterator() {
            return Spliterators.spliterator(this, Spliterator.ORDERED);
        }
    }
    
    

    可以看到List接口中的方法要多了很多。同 Collection 一样,大部分方法一眼就能看出它的作用,只讲解部分特殊的方法。

    List接口不光返回了 Iterator ,也返回特有的 ListIterator。有了这个迭代器,我们可以在任意方向(前、后)遍历List,在迭代过程中修改List,获取迭代器当前在List的位置。

    相比于 Iterator 接口, ListIterator接口多了:向前方向的方法,如hasPrevious、previous,获取位置的方法:nextIndex、previousIndex 等等。具体可以查看源码学习了解。

  • 相关阅读:
    js中定义变量的三种方式const,val,let 的区别
    jquery中attr和prop的区别
    jQuery prop() 方法
    toFixed()方法
    java中匿名类的讲解
    Java序列化的几种方式以及序列化的作用
    classloader加载过程
    有关java中static关键的重写问题
    java泛型的讲解
    真实的周星星,你了解吗?
  • 原文地址:https://www.cnblogs.com/JohnTsai/p/15609869.html
Copyright © 2011-2022 走看看