首页 - 常识问答 - 正文

Java ArrayList是基于数组实现的吗?有些数组可以存放基本类型,为什么List不可以?

日期:2023-4-80 次浏览

ArrayList相关的知识点也是java面试中最频繁出现的点,下面从源码的角度来分析下Arraylist!

1,ArrayList中的属性:ArrayList中的属性主要定义了一个对象数组(Object[]),大小(size),初始容量(DEFAULT_CAPACITY=10)等等,从属性中就可以知道ArrayList的底层就是一个数组,使用泛型E来存放构造器中传入的对象类型,当然ArrayList存放的并不是对象本身,而是对象的引用,所以ArrayList不能存放八个基本类型的数据;

2,ArrayList的主要方法:从下面截图可以看出,ArrayList中的主要方法就是元素的add(增),remove(删),set(改),get(查),而由这四大类方法自然衍生了获取大小,扩容,清空,包含等方法!

下面就主要方法进行分析:

1,add方法(add(i),addAll()等类似):

①,先判断加入元素后的数组大小,如果是小于初始容量则返回初始容量,否则返回+1后的容量值; ②,容量加1,同时跟未加入元素时的数组length比较,如果大于length,则使用grow方法进行扩容;

③, int newCapacity = oldCapacity + (oldCapacity >> 1); >>右移符号,相当于除二,即新容量为老容量的(1+0.5=1.5)倍,再进行判断是否新容量已经超限(Integer.MAX_VALUE - 8),如果超限,则置为最大容量,否则使用Arrays.copyOf复制得到新数组;

2,remove方法(remove其他方法类似):

①,先判断是否下标越界,越界抛出异常,否则继续

②,获取到相应下标的元素;

③,将下标后面的元素使用System.arraycopy往前移动一位; ④,将遗留出的最后一位置为null,让GC进行回收,并返回②中获得的值;

3,get,set方法:比较简单,就是使用指定下标进行数据替换或者获取;

记录几个ArrayList中碰到的坑 :

1,线程不安全:所有的数据存取都是线程不安全的,所以多线程环境要么使用Vector,要么使用CopyOnWriteArrayList;

2,Arraylist是实现了序列化接口的,但使用subList方法返回的是SubList对象,这个对象并没有序列化,在网络传输中会报错的;

3,使用remove方法遇到的坑,因为remove方法重载了两个,remove(int i)和remove(Object o),如果是传入Integer类型的参数,默认调用第二个,则删除元素失败,案例如下:

可以说ArrayList是JAVA开发过程中最常使用的数据结构,底层实现也不难,但是如果不了解的话,面试容易被问倒,更多的JAVA技术会一直持续分享的,敬请关注。。。谢谢!