集合Collection(一):整体架构

【关于作者】

关于作者,目前在蚂蚁金服搬砖任职,在支付宝营销投放领域工作了多年,目前在专注于内存数据库相关的应用学习,如果你有任何技术交流或大厂内推及面试咨询,都可以从我的个人博客(https://0522-isniceday.top/)联系我

1.Collection集合类图

1.1 集合类族谱

从下图中也能看到,Collection接口总共主要有三个继承类:Set、List、Queue。其中Set和List的区别在于有序及无序,Set结构也不允许有重复数据,其中Collection类下又抽象了一层AbstracCollection.class抽象类

image-20210408115824603

思考:

为什么集合的具体实现类都是继承了抽象的集合类,然后再实现了抽象类也实现的接口

(1)首先通过抽象类能够实现部分接口,到了具体的实现类ArrayList、Vector等就可以不去实现,

(2)以后万一直接废弃了AbstractXX.class、那么改造成本也比较低,因为并没有代码会直接申明抽象类对象,而抽象类对象又可以将List

2.族谱顶层的几个类

2.1.IIterable接口

其中Iterable类包含如下方法:

/**
* 
* Returns an iterator over elements of type {@code T}.返回类型T元素上的迭代器,用于foreach遍历
*
* @return an Iterator.
*/
Iterator<T> iterator();


/**
遍历方法
**/
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);
}

补充

default的含义:

jdk1.8之后,接口中能够用default、static修饰方法,实现类可以直接使用被default修饰的方法,但是实现类如果同时继承了两个同样的default方法,那么就需要实现该方法,不然编译器不清楚具体调用的哪个方法。

2.2.Iterator接口

2.2.1 .重要的方法

/**
 * Returns {@code true} if the iteration has more elements.
 * (In other words, returns {@code true} if {@link #next} would
 * return an element rather than throwing an exception.)
 * 
 * @return {@code true} if the iteration has more elements
 */
boolean hasNext();

/**
 * 返回迭代中的下一个元素
 * Returns the next element in the iteration.
 * @return the next element in the iteration
 * @throws NoSuchElementException if the iteration has no more elements
 */
E next();

/**
* 从基础集合中移除此迭代器返回的最后一个元素(可选操作)。 每次调用next只能调用一次此方法。 如果在迭代进行过程中以其他方式(而 * 不是通过调用此方法)修改了基础集合,则未指定迭代器的行为
* 如果是默认实现则会报错,因此如果在使用foreach遍历的场景必须实现该方法
*/
default void remove() {
    throw new UnsupportedOperationException("remove");
}

例如这里我们可以看下ArrayList的迭代器角色的实现:

/**
* 该方法为ArrayList的迭代器容器Itr.class实现的方法
*/
public E next() {
    checkForComodification();
    // cursor游标
    int i = cursor;
    //如果i已经超过了size的值则抛异常
    if (i >= size)
        throw new NoSuchElementException();
    //获取迭代器角色持有的数据
    Object[] elementData = ArrayList.this.elementData;
    if (i >= elementData.length)
        throw new ConcurrentModificationException();
	//游标指针后移一个元素,所以执行完next之后,游标会后移一位
    cursor = i + 1;
    //返回并记录lastRet(记录最后一个元素)的值
    return (E) elementData[lastRet = i];
}

2.2.2 主要用途

用于实现foreach遍历,接口用于定义迭代器的相关约束,作为迭代器模式的迭代器角色

2.3.Collection接口

2.3.1.重要的方法

其中Iterator<E> iterator();使用了简单工厂模式,因此ArrayList、Set结构等实例能够通过该方法返回Iterator实例

/**
 * 返回对此集合中的元素进行迭代的迭代器。 没有关于元素返回顺序的保证(除非此集合是提供保证的某个类的实例)
 * Returns an iterator over the elements in this collection.  There are no
 * guarantees concerning the order in which the elements are returned
 * (unless this collection is an instance of some class that provides a
 * guarantee).
 *
 * @return an <tt>Iterator</tt> over the elements in this collection
 *
 * 其中Collection类继承的Iterable类也包括该方法
 * 启动迭代器类Iterator中定义了遍历的方法,见下面Iterator类详解
 */
Iterator<E> iterator();






2.3.2.全部方法

Collection接口主要定义了集合相关的基本操作:例如基本的增删改,size、isEmpty等基本操作

image-20210407154915089

2.4.AbstracCollection.class

其中主要实现了集合接口的几个基本接口,其中有方法是直接抛出异常,并未完成具体实现,后续可查看其子类AbstractSet、AbstractList的继承情况,其中主要实现的方法如下:

public boolean contains(Object o) {
    Iterator<E> it = iterator();
    if (o==null) {
        while (it.hasNext())
            if (it.next()==null)
                return true;
    } else {
        while (it.hasNext())
            if (o.equals(it.next()))
                return true;
    }
    return false;
}

public Object[] toArray() {
        // Estimate size of array; be prepared to see more or fewer elements
        Object[] r = new Object[size()];
        Iterator<E> it = iterator();
        for (int i = 0; i < r.length; i++) {
            if (! it.hasNext()) // fewer elements than expected
                return Arrays.copyOf(r, i);
            r[i] = it.next();
        }
        return it.hasNext() ? finishToArray(r, it) : r;
}

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 removeAll(Collection<?> c) {
        Objects.requireNonNull(c);
        boolean modified = false;
        Iterator<?> it = iterator();
        while (it.hasNext()) {
            if (c.contains(it.next())) {
                it.remove();
                modified = true;
            }
        }
        return modified;
}

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


image-20210407181959051

2.5.AbstractSet.class

在AbstractCollection.class基础上扩展实现的方法如下

public boolean equals(Object o) {
	//自比则直接返回true
    if (o == this)
        return true;
	//不是集合类型则false
    if (!(o instanceof Set))
        return false;
    Collection<?> c = (Collection<?>) o;
	//size不等则false
    if (c.size() != size())
        return false;
    try {
        //这里就代表元素数量相等、都是集合、再比较元素
        return containsAll(c);
    } catch (ClassCastException unused)   {
        return false;
    } catch (NullPointerException unused) {
        return false;
    }
}

/**
* 计算hashCode的值,用于equals比较
*/
public int hashCode() {
    int h = 0;
    Iterator<E> i = iterator();
    while (i.hasNext()) {
        E obj = i.next();
        if (obj != null)
            //通过累加元素的hashCode的值用于返回,这样就可以保证集合的equal比较就是比较集合中元素的hash值
            h += obj.hashCode();
    }
    return h;
}

/**
* 此实现通过在每个集合上调用size方法来确定哪个是该集合和指定集合中的较小者。 如果此集合具有较少的元素,则实现将对此集合进行迭 * 代,依次检查迭代器返回的每个元素,以查看其是否包含在指定的集合中。 如果包含此类内容,则使用迭代器的remove方法将其从此集合中 * 删除。 如果指定的集合具有较少的元素,则实现将迭代指定的集合,并使用此集合的remove方法从此集合中删除迭代器返回的每个元素。
* 请注意,如果迭代器方法返回的迭代器未实现remove方法,则此实现将引发UnsupportedOperationException 。
*/
public boolean removeAll(Collection<?> c) {
    Objects.requireNonNull(c);
    boolean modified = false;
	//比较删除集合的大小和当前集合的大小,谁的size小就用谁去迭代remove
    if (size() > c.size()) {
        for (Iterator<?> i = c.iterator(); i.hasNext(); )
            modified |= remove(i.next());
    } else {
        for (Iterator<?> i = iterator(); i.hasNext(); ) {
            if (c.contains(i.next())) {
                i.remove();
                modified = true;
            }
        }
    }
    return modified;
}
  

2.6.AbstractList.class

AbstractList.class层级扩展的方法很多,其中包括两个内部类,主要的类及方法如下

/**
* 迭代器Iterator的容器实现类,主要用于遍历持有的数据
*/
private class ListItr extends Itr implements ListIterator<E> {}

/**
* 迭代器实现类Itr的子类,用于增强,其中增强的方法如下,具体增强的方法如下图
*/
private class ListItr extends Itr implements ListIterator<E> {
    
    public boolean hasPrevious() {
            return cursor != 0;
    }
    
    public E previous() {
            checkForComodification();
            try {
                int i = cursor - 1;
                E previous = get(i);
                lastRet = cursor = i;
                return previous;
            } catch (IndexOutOfBoundsException e) {
                checkForComodification();
                throw new NoSuchElementException();
            }
    }
    
}

AbstractList.ListItr.class

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哈哈哈张大侠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值