了解数组列表ArrayList

本文介绍了Java里的数组列表ArrayList,它继承自List接口,使用时和数组类似,能自动调节容量。默认初始长度为10,元素增多时按n = n * 3 / 2 + 1规律扩容。还提及常用方法,如trimToSize(),并分析了访问、插入和删除操作,建议根据情况选择使用。

Java里面的数组列表ArrayList

ArrayList是一个类,该类继承与接口List

在Java里面,虽然可以动态的改变数组的大小

int size = ...;	//	可以动态改变的数
Student[] student = new Student(size);

但是该数组一旦确定了大小,就不容易改变它了。,这时,就体现出了ArrayList的优点了,它使用时,和数组差不多,在对它进行增加或者删除元素时,会自动的调节数组的容量。不需要为其做其他的操作

ArrayList<Student> students = new ArrayList<Student>();	//在Java SE 7之前
ArrayList<Student> students = new ArrayList<>();	//在Java SE 7及之后

上述关于Java SE 7对定义的改变,时为了方便,因为new操作符使用<>语法时,编译器会检查新值是什么,如果复制给一个变量,或传递到某个方法,编译器会检查这个变量、参数或者方法的泛型类型,然后将这个类型放在<>中,上述代码是给了变量 ArrayLisy,所以new后面的<>里面也是Student,关于<>的问题,其实“=”右边的实例如果不加<>,编译器他也不会报错,只会发出一个警告,但是“=”左边一定要加<>,且里面一定要写类型,否者即使报错

ArrayList其实也有有初始长度的,如果初始化时未指明其长度,则其默认长度就是10,但是这个10,和其size不是一个,size()函数获得的是已经存在的元素的长度即个数,而初始化的10是值空间大小,即没有存储数据时,其也占据着内存空间,且初始大小为10(为定义初始大小时)

即如果创建实例化时像上面一样默认创建,则初始容量被设置为10。当ArrayList中的元素超过10个以后,数组列表的容量大小即内存就会重新分配,使数组的大小增长到16,然后通过调试,我们可以发现动态增长的容量大小变化为:10->16->25->38->…,而如果我们实例化时,指定其大小如

List arrayList = new ArrayList(6);

将ArrayList的默认容量设置为6。当ArrayList中的元素超过6个以后,会重新分配内存空间,使数组的大小增长到10。
可以通过调试看到动态增长的数量变化:6->10->16->25->…

最后可以得出其变化规律为n = n * 3 / 2 + 1,而不是简单的n = n * 2;

//我们可以利用add为其添加值,不像数组使用的是a[i] = ...;
student.add(new Student("name",id));

数组列表管理着对象引用的一个内部数组,一旦空间被用尽了,这时,数组列表的强大就体现出来了,如果你继续add,但是,空间已经满了,则数组列表就会自动的创建一个更大的空间的数组。然后将里面的对象全都拷贝到新建的数组里面,从而实现动态自动扩大的效果

一些ArrayList的常用方法

方法功能
ArrayList<>()构造一个空数组列表
ArrayList<>(int initialCapacity)构造一个空数组列表,initialCapacity数组列表的最初容量
boolean add(E obj)在数组列表的尾端添加一个元素,永远返回true,obj为添加的元素
int size()返回数组列表中当前元素的数量,这个值小于或等于列表的容量
trimToSize将数组列表的存储容量削减到当前尺寸
void set(int index,E obj)设置数组列表指定位置的元素值,这个操作将覆盖这个位置的原始内容。index:位置,obj:新的元素
E get(index)获得指定位置的值,index:位置
void add(int index,E obj)向后移动元素,以便插入元素,index:位置,obj:新元素
E remve(int index)删除一个元素,并将后面的元素前移,被删除的元素由返回值i返回,index:被删除元素的位置

trimToSize()方法,一旦确认了数组裂变的当前元素的数量,且不再改变,则可以调用该函数,它可以自动调节当前数组的存储空间数目,垃圾回收期将回收多余的存储空间;

对于数组列表的访问,它不像数组一样,但又和数组一样,因为数组列表也是通过下标访问

for(int i = 0;i < student.size();i++)
{
	System.out.println(student.get(i));	//将数组列表便利
}
//但是一般都是用for each访问
for(Student stu : student)
	System.out.println(stu);//这个和上述代码效果一样

对于删除(remove(int index))和插入(add(int index,E obj)而不是add(E obj)),这两个函数,执行插入或者删除时,由于是在数组的之间发生的变化,就涉及到了,动态改变里面元素位置的变化,对其进行前移或者后移的操作,这样效率比较低,这个时候,就应该考虑是否要使用链表

但是在使用ArrayList时,声明如下,

List<Student> stu = new ArrayList<>();	//一般不使用ArrayList<Student> stu = new ArrayList<>();

前面已经说到了,ArrayList是继承了接口List的一个类,为什么要用 List list = new ArrayList() ,而不用 ArrayList alist = new ArrayList()呢?
问题就在于List接口有多个实现类,现在用的是ArrayList,或许有时候需要换成其它的实现类,如 LinkedList或者Vector等等,利用其多态性,这时你只要改变这一行就行了: List list = new LinkedList(); 其它使用了list地方的代码根本不需要改动。 假设你开始用ArrayList alist = new ArrayList(),这是你就需要该以下ArrayList所有使用了其独有的属性和方法的代码,但是在使用数组列表时,很少用到其独有的方法,所以一般使用List除非有其他特殊的需求。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值