100行代码手写模拟一个ArrayList

一、ArrayList

    首先ArrayList是一个List集合,底层的实现原理是数组,因此我们来手写模拟一下ArrayList,顺便复习下数组和数据结构。

二、结果演示:

 2.1、测试add()、set()、get()方法

2.2、测试clear()方法

2.3、测试remove()方法

三、实现思路

 get() 实现思路:

    首先,需要自定义一个Object类型的数组用来存放数据,然后再定义个size变量,代表输入数字的size,这里需要注意的是objs和size含义不同,一定要区分,objs里面是自定义存放的个数,而size是你设置到List集合中数的个数。

   接下来我们来实现get方法,为了方便测试,我们自定义的get方法有2个,而实际的ArrayList中的get方法只有一个,即根据下标index去查找对应的元素,第一个get方法直接返回当前数组的长度,第二个可以根据传进来的index来查找对应元素。

   解释下第二个get(int index),需要先判断当前传入的Index是不是大于数组总长度,或者小于0,如果是的话直接手动抛出异常,实际上应该是自定义一个异常,里面采用枚举定义,然后这里捕获,为了简化就这样吧。。。如果没有越界就直接输出。

add()实现思路:

    思考一下,如果定义的objs是10,但是用户add进来100个数,这时候就会出现问题,很明显objs存不下来,自然取的话也会是问题,这时候我们考虑让它自动扩容,在ArrayuList中扩容的倍数其实是原有倍数*3/2再加1,具体为什么是这样我们姑且不管(估计和泊松分布有关,就像Map扩容倍数为0.75),假设现在扩容完毕了,那么接下来该怎么处理呢?自然是再定义个新数组,将之前数组中的数据拷贝到新数组中去,但是此刻输出的时候依旧是原来数组中的数,所以这个时候就需要新数组中的数给原来数组进行输出,有点绕,举个例子哈,假如你现在是单身狗(我也是),你自己租一间10多平米的房可以够住了,但是突然有一天你脱单了,那你和女朋友住在一起的话是不是有点挤(因为才10多平米)。那怎么办呢?只能换大点房子住了(新数组),但是住新房子的还是你们2个人,只是把你们2个人换到了大房子,大家慢慢体会哈。在ArrayList源码中是采用了System.arraycopy方法来实现拷贝,我们这里采用最原始的方式手动实现,下面是实现代码以及测试是否可以自动扩容的代码:

set() 实现思路:

    set方法是将数组下标的值改变,很容易就能想到set方法需要定义2个参数,一个是index,一个是Object类型的value,接下来更简单,直接将传进来的value赋值给对应的index位置。

clear() 实现思路:

    clear方法的作用是清除数组中的所有数,因此我们可以循环数组中的所有值,然后给它们分别赋值为null,别忘记给size设置为0,这时候数组中已经没有元素了。

remove() 实现思路:

    其实我个人觉得remove才是整个ArrayList最复杂的方法,在真正的ArrayList源码中用到了很多很多精巧的设计和算法,我们首先来考虑下为什么复杂,比如对移除完的元素需要垃圾回收对吧,什么时候进行垃圾回收?如何回收?这些都设计到了JVM的知识和更加复杂的算法,有兴趣的话大家可以自行研究,这里我只是简单实现了对数字和字符串的删除接下来说下思路。

四、总结

    ArrayList源码中远远比我们这个手写过程复杂,我们需要学习的是写JDK源码大佬们的思想。

 

查看更多内容请关注公众号:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值