Java 集合框架之Collection源码解析

12 篇文章 0 订阅
1 篇文章 0 订阅

一、前言

在实际的开发场景中我们经常会用的集合,什么情况下选择什么类型的集合是Java使用过程中开发人员必须掌握的技能,而且在很多面试过程中,这一块的内容也是必考的。在很多技术博客上已经有很多分享和总结,今天我将从各个接口和集合类的源码分析入手,深入了解集合的底层结构。

《Java 集合框架之Set系列源码解析》
《Java集合之Map系列源码解析》

二、总览

集合框架图

三、Collection

Collection集合层次结构中的根接口,继承Iterable接口,也就是迭代器。

那我们先来看一下Iterable接口源码,这个接口又定义了哪些方法。

在源码注释中对这个接口的解释是“实现这个接口允许一个对象作为“for-each循环”语句的目标”
Iterable接口是从jdk1.5版本开始有的,而forEach方法和**spliterator()**方法则是从jdk1.8才有的。

public interface Iterable<T> {

    Iterator<T> iterator();

    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);
    }
}

方法中涉及到两个接口ConsumerSpliterator,也是jdk1.8引入的,这里就不展开详细分析了。稍后我们对Spliterator这个接口重点解析,现在回到Collection接口上

public interface Collection<E> extends Iterable<E> {
	//返回此集合中的元素数
	int size();
	//判断是否为空
	boolean isEmpty();
	//判断是否包含指定元素
	boolean contains(Object o);
	//返回此集合中元素的迭代器
	Iterator<E> iterator();
	//返回一个数组,该数组包含此集合中的所有元素
	Object[] toArray();
	//返回数组的运行时类型是指定数组的运行时类型
	<T> T[] toArray(T[] a);
	//返回true表示新增元素成功,返回false表示元素已存在
	boolean add(E e);
	//移除指定元素
	boolean remove(Object o);
	//判断是否包含指定集合的所有元素
	boolean containsAll(Collection<?> c);
	//注释中标明optional operation,表示子类可以不实现
	boolean addAll(Collection<? extends E> c);
	//注释中标明optional operation,表示子类可以不实现
	boolean removeAll(Collection<?> c);

	//@since 1.8 移除满足条件的所有元素
	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;
    }

	//注释中标明optional operation,表示子类可以不实现
    //仅保留此集合中包含在指定集合中的元素
    boolean retainAll(Collection<?> c);

	注释中标明optional operation,表示子类可以不实现
    //从该集合中删除所有元素
    void clear();

    //具体看Set和List的实现
    boolean equals(Object o);

    int hashCode();

    //@since 1.8 返回可分割迭代器
    @Override
    default Spliterator<E> spliterator() {
        return Spliterators.spliterator(this, 0);
    }

    //@since 1.8 返回以此集合作为源的Stream
    default Stream<E> stream() {
        return StreamSupport.stream(spliterator(), false);
    }

    //since 1.8 返回可能并行的以此集合作为源的Stream
    default Stream<E> parallelStream() {
        return StreamSupport.stream(spliterator(), true);
    }
}

从上面源码中可以看到其中有5个default修饰的方法(default 是 java 8新引入的关键字,也可称为Virtual
extension methods——虚拟扩展方法。是指,在接口内部包含了一些默认的方法实现,也就是接口中可以包含方法体,这打破了Java之前版本对接口的语法限制,从而使得接口在进行扩展的时候,不会破坏与接口相关的实现类代码)
通过stream()方法我们可以知道,所有继承Collection接口的类就都可以支持Stream方法了,继而支持Lambda表达式,继而可以并行执行某个动作。

关于Spliterator接口Spliterators静态类
Spliterator用于遍历和划分源元素的对象。Spliterator所覆盖的元素的源可以是数组、集合、IO通道或生成器函数;jdk1.8发布后,对于并行处理的能力大大增强,Spliterator就是为了并行遍历元素而设计的一个迭代器,jdk1.8中的集合框架中的数据结构都默认实现了spliterator。在Spliterator接口中内部定义了一个内部接口OfPrimitive,专门用于基础数据的Spliterator。
Spliterators用于操作或创建Spliterator实例的静态类,Spliterators类中又专门针对int,long,double三种数据类型的数据源定义了OfIntOfLongOfDouble三个继承OfPrimitive接口的接口。

以下是官方文档的描述

Interface Spliterator<T>

Type Parameters:
T - the type of elements returned by this Spliterator

All Known Subinterfaces:
Spliterator.OfDouble, Spliterator.OfInt, Spliterator.OfLong, Spliterator.OfPrimitive<T,T_CONS,T_SPLITR>

All Known Implementing Classes:
Spliterators.AbstractDoubleSpliterator, Spliterators.AbstractIntSpliterator, Spliterators.AbstractLongSpliterator, Spliterators.AbstractSpliterator

上面已知的实现类均为Spliterators类的内部类。

在Spliterator接口中还定义了Characteristic value 特征值,作为Spliterators静态类创建Spliterator的参数

//元素有序
public static final int ORDERED    = 0x00000010;

//元素不重复
public static final int DISTINCT   = 0x00000001;

//表示元素顺序按照预定义的顺序,可以通过getComparator 获取排序器,若返回null ,则是按自然排序
public static final int SORTED     = 0x00000004;

public static final int SIZED      = 0x00000040;

//表示数据源保证元素不会为空
public static final int NONNULL    = 0x00000100;

//表示在遍历的过程中不能添加、替换、删除元素
public static final int IMMUTABLE  = 0x00000400;

//表示元素可以被多个线程安全并发得修改而不需要外部的同步
public static final int CONCURRENT = 0x00001000;

public static final int SUBSIZED = 0x00004000;

这些特征值将在Set,List等接口中有所体现。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值