Java List子类ArrayList的实现原理

java中ArrayList的实现原理:

ArrayList的底层是通过数组实现的,即ArrayList对象中维护着一个数组对象,如下:

private static final int DEFAULT_CAPACITY = 10;		                //默认的数组容量
transient Object[] elementData;						//实际存储数据的数组容器
public ArrayList() {							//默认构造方法
	this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;       //由此可以知道ArrayList的最大长度是Integer.MAX_VALUE


由于数组声明长度后不可更改,那么ArrayList是如何实现add功能的呢?


源码如下:

public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }

其中ensureCapacityInternal方法实际上就是为数组扩容如下:

    private void ensureCapacityInternal(int minCapacity) {
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }

        ensureExplicitCapacity(minCapacity);
    }
	
	private void ensureExplicitCapacity(int minCapacity) {
        modCount++;

        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }
	
	private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);
    }
扩容的思想:就是什么一个新的长度更大的数组,然后将之前数组中的元素复制到该数组中。

这样数据就有了存储的地方,最后需要解决的一个问题就是 迭代器模式

首先ArrayList的父子关系如下图所示:


此图来自百度百科里面的集合总父子关系:现在只需要关注 Iterable  Iterator   ListIterator   Collection   List   AbstractCollection   AbstractList   ArrayList这几个类

在逐个解析这些类之前,有必要先温习一下迭代器模式:


虽然JDK中的迭代器模型比上述模型要复杂好多,但是目的都是一样的。简单的理解了上述模型之后,再来看上述的类

Iterable  接口 定义如下:

public interface Iterable<T> {

    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);
    }
}
里面最重要的抽象方法为  iterator()  实质就是返回一个迭代器

实现了该接口的类就能够使用增强for循环了。 

再来看Collection 接口的定义:

public interface Collection<E> extends Iterable<E>
也就是这样 所有Collection接口的实现类都可以使用增强for循环。


然后就是 iterator 接口:

public interface Iterator<E> {

    boolean hasNext();		//是否有下一个元素

    E next();				//获取下一个元素


    default void remove() {
        throw new UnsupportedOperationException("remove");
    }

    default void forEachRemaining(Consumer<? super E> action) {
        Objects.requireNonNull(action);
        while (hasNext())
            action.accept(next());
    }
}

该接口自定义了迭代器需要的最基本的也最重要的方法  hasNext()  next()  实现了这两个方法的迭代器就基本可以用了,但是JDK为了增强ArrayList的特性,为ArrayList又定义了一个迭代器 ListIterator

定义如下:

public interface ListIterator<E> extends Iterator<E> {

    boolean hasNext();

    E next();

    boolean hasPrevious();

    E previous();

    int nextIndex();

    int previousIndex();

    void remove();

    void set(E e);

    void add(E e);
}

可以看到ListIterator继承自Iterator,同时对Iterator做了扩展

下面再来看AbstractCollection

public abstract class AbstractCollection<E> implements Collection<E> {

    protected AbstractCollection() {
    }

    public abstract Iterator<E> iterator();

}
里面其它的一些实现方法都比较简单,同时也不是很重要,里面最重要的一个方法就是 iterator()方法,该方法是获取迭代器的方法。


 再来看List

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

    Iterator<E> iterator();

    ListIterator<E> listIterator();

    ListIterator<E> listIterator(int index);
}

该接口中其它的接口都被我删掉了,我们只看重要的部分 

1.该接口继承自Collection接口   

2.从该接口中可以获取 两种类型的迭代器  a.基类迭代器 Iterator   b.增强类型的迭代器  Listiterator

再来看看AbstractList

    public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {

        protected AbstractList() {
        }

        public Iterator<E> iterator() {
            return new Itr();
        }

        public ListIterator<E> listIterator() {
            return listIterator(0);
        }

        public ListIterator<E> listIterator(final int index) {
            
            return new ListItr(index);
        }

        private class Itr implements Iterator<E> {
            
        }

        private class ListItr extends Itr implements ListIterator<E> {

        }
    }
        

    class SubList<E> extends AbstractList<E> {
        
    }

    class RandomAccessSubList<E> extends SubList<E> implements RandomAccess {
       
    }

里面值得关注的地方就在于该抽象类中包含了两个私有内部类 Itr  和 ListItr 分别实现 Iterator 和ListIterator 。以供为该抽象类的 iterator(),listIterator()方法提供返回值。

另外比较有趣的是,这个类文件中包含了3个类定义,是比较少见的一种写法,实际上一个类文件中有多个类时只要保证只有一个public 的类,并且该类的名称了文件名相同,即可。


最后需要看的就是 ArrayList对象了

定义如下:

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable

该类就并没有什么特别值得关注的地方了,仅仅是实现了,而实现的思想就是使用数组作为元素的存储了。

另外我们再来关注一下,ArrayList里面维护的两个内部类:

Itr  和  ListItr

private class Itr implements Iterator<E> {
	int cursor;
	int lastRet = -1; // index of last element returned; -1 if no such
	int expectedModCount = modCount;

	public boolean hasNext() {
		return cursor != size;
	}

	public E next() {
		int i = cursor;
		Object[] elementData = ArrayList.this.elementData;
		cursor = i + 1;
		return (E) elementData[lastRet = i];
	}

	public void remove() {
		ArrayList.this.remove(lastRet);
		cursor = lastRet;
		lastRet = -1;
	}
}
可见 Itr中维护着ArrayList中的存储数据的elementData数组对象,维护的目的就是为了对Iterator接口中的方法进行实现。

ListItr 当然也是一样。




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值