• 【Java】Collection子接口:其一 List 列接口


    Collection子接口 其一:List接口List

    接口存储结构:元素有序,且可重复,每个元素都有对应的索引
    根据索引获取容器元素

    实现类有:ArrayList、LinkedList、Vector

    三个实现类的异同?

    - 都实现了List接口,存储数据的特点相同、存储有序的、可重复的数据 

    - ArrayList  是List接口的主要实现类,线程不安全的,但是效率高,底层Object[] elementData存储

    - LinkedList  双向链表结构存储,对于插入和删除频繁操作,效率比ArrayList高

    - Vector  初代List接口实现类,线程安全,效率低。底层Object[]存储

    List的接口常用方法【索引支持】

    在指定索引位置添加元素

    public void add(int index, E element)

        /**
         * Inserts the specified element at the specified position in this
         * list. Shifts the element currently at that position (if any) and
         * any subsequent elements to the right (adds one to their indices).
         *
         * @param index index at which the specified element is to be inserted
         * @param element element to be inserted
         * @throws IndexOutOfBoundsException {@inheritDoc}
         */
        public void add(int index, E element) {
            rangeCheckForAdd(index);
    
            ensureCapacityInternal(size + 1);  // Increments modCount!!
            System.arraycopy(elementData, index, elementData, index + 1,
                             size - index);
            elementData[index] = element;
            size++;
        }

    从参数的容器对象的索引位置开始到结尾,添加元素到调用此方法的容器对象

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

        /**
         * Inserts all of the elements in the specified collection into this
         * list, starting at the specified position.  Shifts the element
         * currently at that position (if any) and any subsequent elements to
         * the right (increases their indices).  The new elements will appear
         * in the list in the order that they are returned by the
         * specified collection's iterator.
         *
         * @param index index at which to insert the first element from the
         *              specified collection
         * @param c collection containing elements to be added to this list
         * @return <tt>true</tt> if this list changed as a result of the call
         * @throws IndexOutOfBoundsException {@inheritDoc}
         * @throws NullPointerException if the specified collection is null
         */
        public boolean addAll(int index, Collection<? extends E> c) {
            rangeCheckForAdd(index);
    
            Object[] a = c.toArray();
            int numNew = a.length;
            ensureCapacityInternal(size + numNew);  // Increments modCount
    
            int numMoved = size - index;
            if (numMoved > 0)
                System.arraycopy(elementData, index, elementData, index + numNew,
                                 numMoved);
    
            System.arraycopy(a, 0, elementData, index, numNew);
            size += numNew;
            return numNew != 0;
        }

    按索引获取元素

    public E get(int index)

        /**
         * Returns the element at the specified position in this list.
         *
         * @param  index index of the element to return
         * @return the element at the specified position in this list
         * @throws IndexOutOfBoundsException {@inheritDoc}
         */
        public E get(int index) {
            rangeCheck(index);
    
            return elementData(index);
        }

    返回元素的索引位置,如果是重复了多个元素,返回第一个的位置

    public int indexOf(Object o)

        /**
         * Returns the index of the first occurrence of the specified element
         * in this list, or -1 if this list does not contain the element.
         * More formally, returns the lowest index <tt>i</tt> such that
         * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>,
         * or -1 if there is no such index.
         */
        public int indexOf(Object o) {
            if (o == null) {
                for (int i = 0; i < size; i++)
                    if (elementData[i]==null)
                        return i;
            } else {
                for (int i = 0; i < size; i++)
                    if (o.equals(elementData[i]))
                        return i;
            }
            return -1;
        }

    返回元素的索引位置,如果多个重复元素,返回最后一个出现的

    public int lastIndexOf(Object o)

        /**
         * Returns the index of the last occurrence of the specified element
         * in this list, or -1 if this list does not contain the element.
         * More formally, returns the highest index <tt>i</tt> such that
         * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>,
         * or -1 if there is no such index.
         */
        public int lastIndexOf(Object o) {
            if (o == null) {
                for (int i = size-1; i >= 0; i--)
                    if (elementData[i]==null)
                        return i;
            } else {
                for (int i = size-1; i >= 0; i--)
                    if (o.equals(elementData[i]))
                        return i;
            }
            return -1;
        }

    移除参数的索引上的元素,并返回元素

    public E remove(int index)

        /**
         * Removes the element at the specified position in this list.
         * Shifts any subsequent elements to the left (subtracts one from their
         * indices).
         *
         * @param index the index of the element to be removed
         * @return the element that was removed from the list
         * @throws IndexOutOfBoundsException {@inheritDoc}
         */
        public E remove(int index) {
            rangeCheck(index);
    
            modCount++;
            E oldValue = elementData(index);
    
            int numMoved = size - index - 1;
            if (numMoved > 0)
                System.arraycopy(elementData, index+1, elementData, index,
                                 numMoved);
            elementData[--size] = null; // clear to let GC do its work
    
            return oldValue;
        }

    修改指定索引位置的元素

    public E set(int index, E element)

        /**
         * Replaces the element at the specified position in this list with
         * the specified element.
         *
         * @param index index of the element to replace
         * @param element element to be stored at the specified position
         * @return the element previously at the specified position
         * @throws IndexOutOfBoundsException {@inheritDoc}
         */
        public E set(int index, E element) {
            rangeCheck(index);
    
            E oldValue = elementData(index);
            elementData[index] = element;
            return oldValue;
        }

    截取一段,返回指定起始位置到结束位置的元素到一个新的容器上 【返回子集合】

    public List<E> subList(int fromIndex, int toIndex)

        /**
         * Returns a view of the portion of this list between the specified
         * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive.  (If
         * {@code fromIndex} and {@code toIndex} are equal, the returned list is
         * empty.)  The returned list is backed by this list, so non-structural
         * changes in the returned list are reflected in this list, and vice-versa.
         * The returned list supports all of the optional list operations.
         *
         * <p>This method eliminates the need for explicit range operations (of
         * the sort that commonly exist for arrays).  Any operation that expects
         * a list can be used as a range operation by passing a subList view
         * instead of a whole list.  For example, the following idiom
         * removes a range of elements from a list:
         * <pre>
         *      list.subList(from, to).clear();
         * </pre>
         * Similar idioms may be constructed for {@link #indexOf(Object)} and
         * {@link #lastIndexOf(Object)}, and all of the algorithms in the
         * {@link Collections} class can be applied to a subList.
         *
         * <p>The semantics of the list returned by this method become undefined if
         * the backing list (i.e., this list) is <i>structurally modified</i> in
         * any way other than via the returned list.  (Structural modifications are
         * those that change the size of this list, or otherwise perturb it in such
         * a fashion that iterations in progress may yield incorrect results.)
         *
         * @throws IndexOutOfBoundsException {@inheritDoc}
         * @throws IllegalArgumentException {@inheritDoc}
         */
        public List<E> subList(int fromIndex, int toIndex) {
            subListRangeCheck(fromIndex, toIndex, size);
            return new SubList(this, 0, fromIndex, toIndex);
        }
    
        static void subListRangeCheck(int fromIndex, int toIndex, int size) {
            if (fromIndex < 0)
                throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
            if (toIndex > size)
                throw new IndexOutOfBoundsException("toIndex = " + toIndex);
            if (fromIndex > toIndex)
                throw new IllegalArgumentException("fromIndex(" + fromIndex +
                                                   ") > toIndex(" + toIndex + ")");
        }

    List支持的三种遍历方式

    public class Array {
        public static void main(String[] args) {
            List list = new ArrayList();
            list.add("元素1");
            list.add("元素2");
            list.add("元素3");
            list.add("元素4");
            list.add("元素5");
            list.add("元素6");
    
            // 第一种 迭代器实现遍历
            Iterator iterator = list.iterator();
    
            while (iterator.hasNext()){
                System.out.println(iterator.next());
            }
    
            // 第二种 ForEach
            for (Object object : list) {
                System.out.println(object);
            }
    
            // 第三种 For
            for (int i = 0; i < list.size(); i++) {
                System.out.println(list.get(i));
            }
        }
    }

    注意点: remove的重载

    如何判断注入的是按元素删除?还是按索引删除?

    - 按元素删除,建议使用 new Integer(10) 这样对基本类型数据包装再注入   arrayList.remove(new Integer(5));

    - 按索引删除,默认注入数字值即可   arrayList.remove(3);


    ArrayList的底层源码查看【未完待续...】

    JDK8 

    底层elementData初始化为0

    但是注释依赖没改,仍然称为10初始化容量

    只有在第一次调用add后初始化10的容量,再往后大于10【右移1 除2】增加1.5倍容量

  • 相关阅读:
    Http方法:Get请求与Post请求的区别
    udev和rules使用规则
    c++中的动态内存分配
    c++中重载运算符
    c++中静态成员函数
    c++中值传递,址传递,引用传递
    c++中实现单例模式singleton class
    [Windows篇] 在windows 10上源码编译gtest 并编写CMakeLists.txt
    [Ubuntu篇] 在ubuntu上源码编译gtest,编写gtest-config.cmake并测试
    使用boost data_time模块来获取毫秒级时间并转换为string字符串
  • 原文地址:https://www.cnblogs.com/mindzone/p/12741188.html
Copyright © 2020-2023  润新知