看看源码 -- Java集合(顶级接口篇)

看看源码 -- Java集合(顶级接口篇)

Scroll Down

集合与数组的区别:

  • 数组的长度在初始化时指定, 只能保存定长的数据, 而集合可以保存数量不确定的数据, 同时可以保存具有映射关系的数据
  • 数组元素即可以是基本数据类型, 也可以是对象, 集合里只能保存对象, 基本数据类型需要转为包装类才可以放入集合中

Ok, 先来个亲手整理的族谱图

Java集合族谱图

顶级接口

集合的顶级接口为Collection<E>, 该接口实现了Iterable<E>接口

Iterable<E>

实现这个接口就允许对象使用增强for循环, 也就是for-each循环

接口默认方法(1.8)

default void forEach(Consumer<? super T> action) {
    Objects.requireNonNull(action);
    for (T t : this) {
        action.accept(t);
    }
}
// 获得可拆分迭代器
default Spliterator<T> spliterator() {
    return Spliterators.spliteratorUnknownSize(iterator(), 0);
}

接口方法

Iterator<T> iterator();

Iterator

public interface Iterator<E> {
    // 是否还有下一个元素
    boolean hasNext();

    // 获得下一个元素
    E next();
    
    // 默认使用remove方法会抛出异常
    default void remove() {
        throw new UnsupportedOperationException("remove");
    }

    // 遍历剩余元素
    default void forEachRemaining(Consumer<? super E> action) {
        Objects.requireNonNull(action);
        while (hasNext())
            action.accept(next());
    }
}

Iterator<T>Spliterator<T>

  • Spliterator与Iterator一样, 都是用于遍历集合中的元素, 但Spliterator是为了并行执行而设计
  • Spliterator不是线程安全的, Stream依靠Spliterator实现
  • 注意: 迭代器返回的值是一个新的值, 修改迭代器返回的值是不会影响原集合中的元素的

Collection<E>简单方法

// 状态获取
int size();
boolean isEmpty();

// 增删
boolean add(E e);
boolean remove(Object o);
boolean addAll(Collection<? extends E> c);
boolean removeAll(Collection<?> c);
boolean retainAll(Collection<?> c); // 删除c集合不包含的元素, 也就是再原集合上保留交集
void clear();

// 转换
Object[] toArray();
<T> T[] toArray(T[] a);

// 查询
boolean contains(Object o);
boolean containsAll(Collection<?> c);

boolean equals(Object o);
int hashCode();

Collection<E>默认方法

// 条件删除
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;
}

// 重写的Iterable接口的默认方法, stream 和 parallelStream 都依赖这个可拆分迭代器
@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);
}
// 判定条件接口, Predicate: 判断的, 判定的
public interface Predicate<T> {

 boolean test(T t);

 default Predicate<T> and(Predicate<? super T> other) {
     Objects.requireNonNull(other);
     return (t) -> test(t) && other.test(t);
 }

 default Predicate<T> negate() {
     return (t) -> !test(t);
 }

 default Predicate<T> or(Predicate<? super T> other) {
     Objects.requireNonNull(other);
     return (t) -> test(t) || other.test(t);
 }

 // 获取判定与某个对象是否相等的条件
 static <T> Predicate<T> isEqual(Object targetRef) {
     return (null == targetRef)
             ? Objects::isNull
             : object -> targetRef.equals(object);
 }

 // 获取某个条件对象的反条件
 static <T> Predicate<T> not(Predicate<? super T> target) {
     Objects.requireNonNull(target);
     return (Predicate<T>)target.negate();
 }
}

AbstractCollection<E>抽象类

AbstractCollection抽象类实现了Collection顶级接口, 提供了一些方法的实现

实现的方法

public boolean isEmpty() {
    return size() == 0;
}

public boolean contains(Object o) {
    Iterator<E> it = iterator();
    if (o==null) {
        while (it.hasNext())
            if (it.next()==null)
                return true;
    } else {
        // 直接调用对象的equals来比较
        while (it.hasNext())
            if (o.equals(it.next()))
                return true;
    }
    return false;
}

public boolean containsAll(Collection<?> c) {
    for (Object e : c)
        if (!contains(e))
            return false;
    return true;
}

public Object[] toArray() {
    // 这里先构建个更当前size一样长得数组
    Object[] r = new Object[size()];
    Iterator<E> it = iterator();
    for (int i = 0; i < r.length; i++) {
        if (! it.hasNext()) // 最终长度还是由迭代器来决定
            return Arrays.copyOf(r, i); // 根据迭代后的长度重新调整数组长度
        r[i] = it.next();
    }
    return it.hasNext() ? finishToArray(r, it) : r;
}

// 将集合元素转为数组放到传入的数组a中
public <T> T[] toArray(T[] a) {
    int size = size();
    // 如果a的长度不够就重新创建一个
    T[] r = a.length >= size ? a :
    (T[])java.lang.reflect.Array
        .newInstance(a.getClass().getComponentType(), size);
    Iterator<E> it = iterator();

    for (int i = 0; i < r.length; i++) {
        if (! it.hasNext()) { //如果没有下一个元素了
            if (a == r) {
                r[i] = null; //使用null元素终止
            } else if (a.length < i) {
                return Arrays.copyOf(r, i); // 如果a短了, 直接重新复制一个新的返回回去
            } else { 
                // 如果a是够长的, 那直接复制到a去就好了, 把多余的全部赋值为空
                System.arraycopy(r, 0, a, 0, i);
                if (a.length > i) {
                    a[i] = null;
                }
            }
            return a; //把a返回回去
        }
        // 如果还有下一个就直接赋值
        r[i] = (T)it.next();
    }
    // 重新构建的都还不够长那就继续复制
    return it.hasNext() ? finishToArray(r, it) : r;
}

// 默认让添加元素不支持
public boolean add(E e) {
    throw new UnsupportedOperationException();
}

// 只要添加一个都会返回成功true, 不过子类不重写add也不会成功
public boolean addAll(Collection<? extends E> c) {
    boolean modified = false;
    for (E e : c)
        if (add(e))
            modified = true;
    return modified;
}

// 删除某个元素,默认删除第一个找到的元素
public boolean remove(Object o) {
    Iterator<E> it = iterator();
    if (o==null) {
        while (it.hasNext()) {
            if (it.next()==null) {
                it.remove();
                return true;
            }
        }
    } else {
        while (it.hasNext()) {
            if (o.equals(it.next())) {
                it.remove();
                return true;
            }
        }
    }
    return false;
}

public boolean retainAll(Collection<?> c) {
    Objects.requireNonNull(c);
    boolean modified = false;
    Iterator<E> it = iterator();
    while (it.hasNext()) {
        if (!c.contains(it.next())) {
            it.remove();
            modified = true;
        }
    }
    return modified;
}

public void clear() {
    Iterator<E> it = iterator();
    while (it.hasNext()) {
        it.next();
        it.remove();
    }
}

public String toString() {
    Iterator<E> it = iterator();
    if (! it.hasNext())
        return "[]";

    StringBuilder sb = new StringBuilder();
    sb.append('[');
    for (;;) {
        E e = it.next();
        sb.append(e == this ? "(this Collection)" : e);
        if (! it.hasNext())
            return sb.append(']').toString();
        sb.append(',').append(' ');
    }
}

总结一下: 可以看到, 已经实现的方法基本都是通过迭代器来完成的