Java 集合系列(5): Collection接口源码

package java.util;

import java.util.function.Predicate;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

/**
 *1.Collection接口是集合继承关系中的根接口(root interface),有些集合允许重复元素,  
 *  有些集合有序,JDK不提供本接口的实现,只提供子接口的实现(例如Set,List)  
 *2.所有实现Collection(或者其子接口)的类都必须包含两个构造函数:无参的构造函数,  
 *  以及参数为Collection的拷贝构造函数  
 *
 * @author  Josh Bloch
 * @author  Neal Gafter
 * @see     Set
 * @see     List
 * @see     Map
 * @see     SortedSet
 * @see     SortedMap
 * @see     HashSet
 * @see     TreeSet
 * @see     ArrayList
 * @see     LinkedList
 * @see     Vector
 * @see     Collections
 * @see     Arrays
 * @see     AbstractCollection
 * @since 1.2
 */

public interface Collection<E> extends Iterable<E> {
    //Query Operations 查询操作

	//返回集合中存在的元素数目,如果元素的数目超过Integer.MAX_VALUE,返回Integer.MAX_VALUE 
    int size();

    //当集合不包含任何元素时,返回true  
    boolean isEmpty();

    //如果集合中包含至少一个指定对象,返回true    
    boolean contains(Object o);

    //返回可以遍历集合元素的迭代器    
    Iterator<E> iterator();

    //返回集合中所有元素组成的数组,数组元素的返回顺序要和迭代器访问集合元素的返回顺序一样   
    Object[] toArray();

    //返回包含此 collection 中所有元素的数组;返回数组的运行时类型与指定数组的运行时类型相同。   
    <T> T[] toArray(T[] a);

    
    //Modification Operations(修改操作)

    //如果集合不允许重复元素,且集合中已经含有该元素,返回false    
    boolean add(E e);

    //从此 collection 中移除指定元素的单个实例,如果集合中存在指定元素返回true。    
    boolean remove(Object o);


    // Bulk Operations 批量操作

    
    //如果此 collection 包含指定 collection 中的所有元素,则返回 true。    
    boolean containsAll(Collection<?> c);

    //将指定 collection 中的所有元素都添加到此 collection 中    
    boolean addAll(Collection<? extends E> c);

    //移除此 collection 中那些也包含在指定 collection 中的所有元素(可选操作)。   
    boolean removeAll(Collection<?> c);

    /**
     * 移除集合中满足给定条件的所有元素,错误或者运行时异常发生在迭代时或者把条件传递给调用者的时候。
     *
     * @implSpec
     * 默认的实现贯穿了使用迭代器iterator的集合的所有元素。每一个匹配的元素都将被用Iterator接口中的
     * remove()方法移除。如果集合的迭代器不支持移除,则在第一次匹配时就会抛出异常 UnsupportedOperationException
     *
     * @param filter 令元素移除成功的条件
     * @return {@code true} 如果所有的元素都被移除
     * @throws NullPointerException 如果有这个过滤器是空的
     * @throws UnsupportedOperationException 如果元素不能被从该集合中移除。如果一个匹配元素不能被移除,
     *         通常来说,它就不支持移除操作,这时可能抛出这个异常。
     * @since 1.8
     */
    default boolean removeIf(Predicate<? super E> filter) { //Java8在接口中新引入了一种default方法。目的是保留原先的结构,只将改动加入到接口中。
        Objects.requireNonNull(filter);  //如果有这个过滤器是空则抛出NullPointerException异常
        boolean removed = false;         //定义的一个判断是否被移除的标志
        final Iterator<E> each = iterator(); //final修饰的类,我们只能用,不用继承,被final修饰的变量就是一个常量,只能赋值一次。
        while (each.hasNext()) {
            if (filter.test(each.next())) { //删除符合过滤器的元素
                each.remove();
                removed = true;
            }
        }
        return removed;
    }

    //仅保留此 collection 中那些也包含在指定 collection 的元素(可选操作)
    boolean retainAll(Collection<?> c);

    //移除此 collection 中的所有元素(可选操作),如果此collection不支持清除操作则抛出UnsupportedOperationException异常。
    void clear();


    // Comparison and hashing(比较和散列)

    /**
     * 比较此 collection 与指定对象是否相等。通过覆盖,实现list与list相等,set与set相等    
     * @see Object#equals(Object)
     * @see Set#equals(Object)
     * @see List#equals(Object)
     */
    boolean equals(Object o);

    /**
     * @return 返回此 collection 的哈希码值。    
     *
     * @see Object#hashCode()
     * @see Object#equals(Object)
     */
    int hashCode();

    /**
     * Creates a {@link Spliterator} over the elements in this collection.
     *
     * Implementations should document characteristic values reported by the
     * spliterator.  Such characteristic values are not required to be reported
     * if the spliterator reports {@link Spliterator#SIZED} and this collection
     * contains no elements.
     *
     * <p>The default implementation should be overridden by subclasses that
     * can return a more efficient spliterator.  In order to
     * preserve expected laziness behavior for the {@link #stream()} and
     * {@link #parallelStream()}} methods, spliterators should either have the
     * characteristic of {@code IMMUTABLE} or {@code CONCURRENT}, or be
     * <em><a href="Spliterator.html#binding">late-binding</a></em>.
     * If none of these is practical, the overriding class should describe the
     * spliterator's documented policy of binding and structural interference,
     * and should override the {@link #stream()} and {@link #parallelStream()}
     * methods to create streams using a {@code Supplier} of the spliterator,
     * as in:
     * <pre>{@code
     *     Stream<E> s = StreamSupport.stream(() -> spliterator(), spliteratorCharacteristics)
     * }</pre>
     * <p>These requirements ensure that streams produced by the
     * {@link #stream()} and {@link #parallelStream()} methods will reflect the
     * contents of the collection as of initiation of the terminal stream
     * operation.
     *
     * @implSpec
     * The default implementation creates a
     * <em><a href="Spliterator.html#binding">late-binding</a></em> spliterator
     * from the collections's {@code Iterator}.  The spliterator inherits the
     * <em>fail-fast</em> properties of the collection's iterator.
     * <p>
     * The created {@code Spliterator} reports {@link Spliterator#SIZED}.
     *
     * @implNote
     * The created {@code Spliterator} additionally reports
     * {@link Spliterator#SUBSIZED}.
     *
     * <p>If a spliterator covers no elements then the reporting of additional
     * characteristic values, beyond that of {@code SIZED} and {@code SUBSIZED},
     * does not aid clients to control, specialize or simplify computation.
     * However, this does enable shared use of an immutable and empty
     * spliterator instance (see {@link Spliterators#emptySpliterator()}) for
     * empty collections, and enables clients to determine if such a spliterator
     * covers no elements.
     *
     * @return a {@code Spliterator} over the elements in this collection
     * @since 1.8
     */
    @Override
    default Spliterator<E> spliterator() {
        return Spliterators.spliterator(this, 0);
    }

    /**
     * Returns a sequential {@code Stream} with this collection as its source.
     *
     * <p>This method should be overridden when the {@link #spliterator()}
     * method cannot return a spliterator that is {@code IMMUTABLE},
     * {@code CONCURRENT}, or <em>late-binding</em>. (See {@link #spliterator()}
     * for details.)
     *
     * @implSpec
     * The default implementation creates a sequential {@code Stream} from the
     * collection's {@code Spliterator}.
     *
     * @return a sequential {@code Stream} over the elements in this collection
     * @since 1.8
     */
    default Stream<E> stream() {
        return StreamSupport.stream(spliterator(), false);
    }

    /**
     * Returns a possibly parallel {@code Stream} with this collection as its
     * source.  It is allowable for this method to return a sequential stream.
     *
     * <p>This method should be overridden when the {@link #spliterator()}
     * method cannot return a spliterator that is {@code IMMUTABLE},
     * {@code CONCURRENT}, or <em>late-binding</em>. (See {@link #spliterator()}
     * for details.)
     *
     * @implSpec
     * The default implementation creates a parallel {@code Stream} from the
     * collection's {@code Spliterator}.
     *
     * @return a possibly parallel {@code Stream} over the elements in this
     * collection
     * @since 1.8
     */
    default Stream<E> parallelStream() {
        return StreamSupport.stream(spliterator(), true);
    }
}

下面三个方法里面用到了几个JDK8里面才出现的类:Spliterator接口,Spliterators类,StreamSupport类,Stream接口,BaseStream接口。上面还有一个removeIf这个JDK8才出现的方法也用到了Predicate这个接口。我会在下面的分析当中分析完了,再来看看这几个方法。


实际练习代码:

public static void main(String[] args) {

    List<Integer> list = new ArrayList<>();
    list.add(1);
    list.add(2);
    list.add(3);
    list.add(4);
    list.removeIf(s -> s%2==0);               // 过滤掉模2等于0的数
    list.forEach(s -> System.out.println(s)); // 输出 1 3

    List<String> strings = new ArrayList<>();
    strings.add("ab");
    strings.add("ac");
    strings.add("bc");
    strings.add("cd");
    Predicate<String> predicate = (s) -> s.startsWith("a"); // 这里单独定义了过滤器
    strings.removeIf(predicate);                            // 过滤掉以"a"开头的元素
    strings.forEach(s -> System.out.println(s));            // 输出 bc cd
}



参考:https://blog.csdn.net/HelloMrZheng/article/details/70148300

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值