List数据结构的实现(JDK1.8)

Java深入篇~04.List数据结构的实现(JDK1.8)

前言

       通常程序总是根据运行之后才知道的某些条件去创建对象。在此之前并不知道所需对象的数量,甚至也不知道对象的类型。为了解决这个问题,则需要在任意时刻任意位置来创建这个所需要的对象。这样一来,数组是肯定行不通的。因为数组的尺寸是固定的不可改变的。所以在大多数编程语言里面都会提供某种方法来解决。比如C++有STL,而Java则有一套容器类。

       C++ STL容器

       在集合类的基本类型里,分别有List,Set,Map,Queue。容器提供了相当完善的方法来保存对象,我们可以用它们来解决很多的问题。

List

       List可以将元素维护在特定的序列中,List接口在Collection的基础上添加了大量的方法,使得可以在List中间插入和移除元素。

       本人过去也写过和List数据结构相关的博客。欢迎大家可以点进去看~嘿嘿

       线性表的基本实现和概念

       顺序表的操作

       双链表的操作

       栈和队列的基本概念

       顺序栈和链栈

       使用自定义的栈来优化二叉树的遍历

List的类型

       基本的顺序存储 : ArrayList。从名字就可以看出,这是一个数组的List,底层实现的则是动态数组,数据结构类似顺序表。底层原理类似前面说过的StringBuilder,但也不太一样。ArrayList的优点就是随机访问效率高。但是中间插入和删除则就有点慢了。在"顺序表的操作"那篇博客里说过具体原因。

       链式数据存储:LinkedList。它的优点就是插入和删除的效率高,但是访问中间任何一个元素都需要遍历,所以随机访问效率不如ArrayList。在线性表的基本实现和概念里面有具体原因。

ArrayList

       ArrayList底层是一个动态数组,在初次new它的时候,会构建一个大小为10的空列表。

	public Arst() {
   
	        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
	    }

       当ArrayList的数组容量不够用的时候,则会对数组的长度进行扩容。和StringBuilder不同的是,StringBuilder每次扩容的量是当前长度的一倍+2。而ArrayList则是扩容当前长度的0.5倍。所以,在资源上,ArrayList每次多出的容量会比StringBuilder小。ArrayList的构造方法还可以手动设置初始大小。如果用户在使用ArrayList之前就已经知道最少要存储多少数据,则可以将初始长度设置到最小值,这样可以减少扩容的次数,进一步微妙的提升效率。

	private void grow(int minCapacity) {
   
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

add方法

       ArrayList的add方法既可以直接在尾部添加元素,也可以根据索引来添加元素。其过程则是先判断容量是否够用,不够用则扩容,够用则直接在数组的索引位置后面的一个位置添加进去。ArrayList和StringBuilder一样,数组的长度并不等于容器的长度。当要根据索引来添加元素的时候,可能有人会想到循环,这样做也可以。但是为了效率则可以使用System.arraycopy在指定的位置腾出一个空间来存储需要存储的值。

尾部插入
	public boolean add(E e) {
   
	        ensureCapacityInternal(size + 1);
	        elementData[size++] = e;
	        return true;
	    }
索引插入
	public void add(int index, E element) {
   
	        rangeCheckForAdd(index);
	
	        ensureCapacityInternal(size + 1);  // Increments modCount!!
	        System.arraycopy(elementData, index, elementData, index + 1,
	                         size - index);
	        elementData[index] = element;
	        size++
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 31
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值