Java集合系列(三)-List、Set和Queue

2019-07-03 00:00:00 java 集合 系列

Sean:有足乐专栏导航zhuanlan.zhihu.com《Java集合系列(三)-List、Set和Queue》

List、Set和Queue

List、Queue和Set都是直接继承自Collection,但是又各自有所不同。除了Collection的接口之外,还有自己新增的接口。

1、 List

List是有序的队列,每一个元素都有自己的索引,索引从0开始依次加一。List集合中允许有相同的元素。

List有自己的api接口,主要是添加、删除、获取、修改指定位置的元素等。我们来看一下源码。

package java.util;

import java.util.function.UnaryOperator;

public interface List<E> extends Collection<E> {
    //查询操作 
    /**  * 返回此集合中元素的数量,如果超过Integer.MAX_VALUE,那么返回Integer.MAX_VALUE((2>>31) - 1)。  */
    int size();

    /**  * 此集合中没有元素返回true  */
    boolean isEmpty();

    boolean contains(Object o);

    Iterator<E> iterator();

    Object[] toArray();

    <T> T[] toArray(T[] a);

    // 修改操作 
    boolean add(E e);

    boolean remove(Object o);

    // 包含     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);

    /**  * 使用了新的参数,可以参考(Java8新特性系列)  * @since 1.8  */
    default void replaceAll(UnaryOperator<E> operator) {
        Objects.requireNonNull(operator);
        final ListIterator<E> li = this.listIterator();
        while (li.hasNext()) {
            li.set(operator.apply(li.next()));
        }
    }

    /**  * 使用了新的参数,可以参考(Java8新特性系列)  * @since 1.8  */
    @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();

    //比较 
    boolean equals(Object o);

    int hashCode();
    // 定位     /**  * 返回指定位置的元素  */
    E get(int index);

    /**  * 在指定位置设置指定元素的值  */

    E set(int index, E element);

    /**  * 指定位置添加元素,后面的元素索引依次+1  */
    void add(int index, E element);

    /**  * 移除指定位置的元素  */
    E remove(int index);


    // 查找操作     // 数组允许有重复,允许有null,允许有多个null 

    /**  * 返回指定元素的第一次出现的索引,如果此列表不包含指定元素返回-1  */

    int indexOf(Object o);

    /**  * 返回指定元素的最后一位置的索引,如果此列表不包含指定元素返回-1  */
    int lastIndexOf(Object o);


    // List Iterators 
    /**  * 返回一个ListIterator,按索引有序。  */
    ListIterator<E> listIterator();

    /**  * 返回指定位置之后数组元素组成的ListIterator,如果位置小于零或者  * 大于数组size,抛出IndexOutOfBoundsException异常  * 但是要注意,listIterator.nextIndex()是从参数开始的  */
    ListIterator<E> listIterator(int index);

    // View 

    /**  * 返回从fromIndex开始(包含)到toIndex(不包含)  * 的子集合,如果fromIndex==toIndex那么返回空集合。  * 返回的集合和此集合拥有相同的支持(方法和属性一样)  * 子集合改变,此集合也会改变。  * 总的来说,子集合指向父集合部分内存空间,操作的是部分父集合数据  */
    List<E> subList(int fromIndex, int toIndex);

    /**  * 使用了新的参数,可以参考(Java8新特性系列)  */
    @Override
    default Spliterator<E> spliterator() {
        return Spliterators.spliterator(this, Spliterator.ORDERED);
    }
}

2、 Set

Set也是直接继承Collection接口,与List区别是Set中不允许有重复元素。不同的实现有不同的判断重复元素依据,比如HashSet是根据hashCode判断,TreeSet是根据compareTo()方法判断。

我们来看Set接口的源码。

package java.util;

public interface Set<E> extends Collection<E> {
    // 查询操作 
    int size();
    boolean isEmpty();
    boolean contains(Object o);
    Iterator<E> iterator();
    Object[] toArray();
    <T> T[] toArray(T[] a);


    // 修改操作 
    boolean add(E e);
    boolean remove(Object o);


    // Bulk Operations 
    boolean containsAll(Collection<?> c);
    boolean addAll(Collection<? extends E> c);
    boolean retainAll(Collection<?> c);
    boolean removeAll(Collection<?> c);
    void clear();


    // 比较     boolean equals(Object o);
    int hashCode();
    @Override
    default Spliterator<E> spliterator() {
        return Spliterators.spliterator(this, Spliterator.DISTINCT);
    }
}

Set只提供了一个默认方法,就是spliterator(),这个暂不研究。

3、 Queue

Queue是指队列,是一种先进先出(也可以指定其他顺序)的而数据结构。

package java.util;


/**  * Queue是有序的,按照元素自然顺序,先进先出。  * 也有后进先出的数据结构  * 无论哪种顺序,调用poll()或者remove()方法,head元素将被移除  * 如果是FIFO队列,所有新元素将被插入到尾部,其他种类的队列坑内有不用的规则。  * 所有实现类必须指定顺序的属性(FIFO还是LIFO)  *  * remove()和poll()方法返回队列的头元素。  * 确切地说,从队列中删除的元素是队列的排序策略的一个函数,不同的实现有不同的排序策略。  * remove方法和poll()方法只是返回行为不一样,如果队列是空的,remove()将抛出异常,  * 而poll()会返回null  *  * element()和peek()方法只返回头元素并不会从队列中删除元素。   * 队列接口不定义阻塞队列方法,而阻塞队列方法在并发编程中很常见。这些方法在java.util.  * concurrent.BlockingQueue接口中定义。  *  * 队列的事项通常不允许插入null元素,即使一些实现比如LinkedList没有null的限制。  * 即使在允许null的实现中,也不应该像null那样插入队列  * poll方法用作特殊的返回值,指示队列不包含元素。  */

public interface Queue<E> extends Collection<E> {

    /**  * 给队列插入指定元素,如果没有容量限制的话。  * 如果插入成功返回true,空间不够抛出IllegalStateException异常  */
    boolean add(E e);

    /**  * 同add()方法,不同地方在于空间不够返回false,不抛出异常  */
    boolean offer(E e);

    /**  * 移除队列中的头元素,与poll()不同,如果队列为空会抛出异常  */
    E remove();

    /**  * 移除队列中的head元素,如果队列为空返回null  */
    E poll();

    /**  * 检索队列中的head元素,不会删除,如果队列为空抛出异常  */
    E element();

     /**  * 检索队列中的head元素,不会删除,如果队列为空返回null  */
    E peek();
}

我们讲完了List、Set和Queue接口,接下来是AbstractList、AbstractSet、AbstractQueue。

–完–

    原文作者:Sean
    原文地址: https://zhuanlan.zhihu.com/p/58555431
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。

相关文章