Java中的ArrayList和线性表用法及说明
作者:月下清融析愿
一、线性表
线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列...
线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储。

二、顺序表
顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。
接口的实现

注意事项:
- 接口里的抽象方法一定要重写
- 接口里的默认方法可选重写
- 接口里的空接口不用重写
- 不是接口方法不用重写
- 快捷重写键: ctrl + o
使用方法
现在我们通过数据结构来使用这些方法
数据结构与以往我们练习有最大的不同就是,可以实现自己造轮子
1.display方法
我们来写一个遍历

display可以遍历数据表中的所有元素

这样可以遍历所有数据表中的有效数据
不可以用for each来遍历,因为所有数据都是零,无法区分是否为有效数据



正常来讲,因为现在数据表里没有任何有效数据,所以分割线下面应该是没有数据打印的,但是打印了许多的零是因为用for each来遍历的话所有数据都是零,无法区分是否为有效数据


2.add方法

这里有两个add方法
- 第一个add方法 默认将数据放在数组最后
- 第二个add方法 指定将数据放在数组中某位置
第一个add方法

如果满了,那我们就使用grow来进行扩容,这里使用的是二倍扩容,这里的grow用的是private修饰符,毕竟使用者也无需触碰到扩容

输出结果:

第二个add方法
这个比较抽象,我们先讲一下思路:
- 要将数据插入数组某一位置,那么我们就要把在原先在这个位置上的数据移动到下一个位置,
- 但是有个问题,如果该数据所在的下一个位置上还有数据,就会导致两个数据重叠,
- 因此我们要首先移动最后一个有效数据,
- 在技术上可以实现为 将i下标的数据定义为 有效数据-1 ,即 usedSize-1(有零下标) ,再将i下标的值赋值给i+1 ,直到 i== 插入数据位置,(即pos位置)也要挪动
i = usedSize - 1; [i+1] = [i];//直到挪动完 i==pos
然后将要插入的数据放到pos位置,最终让usedSize++(插入了一个数据就多了一个有效数据)就可以了,但是涉及到数组,我们还要判断是否会溢出.
代码:


看似代码一切正常,但有同学可能会问:
- 如果插入的下标位置是负数怎么办?
- 如果插入的下标位置大于 usedSize 怎么办?
数据结构规定 每次插入数据的位置 不能有空隙 即前驱必须存在 也就是说 插入位置的前一个位置不能是空的
现在我们要实现:
- pos < 0 不可以插入
- pos > usedSize 不可以插入
- pos == usedSize 可以插入
代码:


这一块前面都提到过就不解释了
3.contains 与 indexof 方法

为了能更好的理解这两个方法,请大家依据中间红色字体的要求来编写一段代码
代码:

那如果是引用类型怎么办,那就不能这样比较了,应该用equals来比较
因此不是说数据表只能放整型
4.get方法


如果数据表是空的怎么办

当然也可以再写一个空异常



5.set方法
这个方法的作用是更新,或者说是覆盖旧的数据
因此pos(数据的下标)必须在0到usedSize - 1之间

6.remove方法
这个方法的作用是删除

注意必须是usedSize-1,如果不减一,在数据放满的情况下array[i+1]会越界
7.clear方法

这个方法很简单,就是清空数组,因为之前我们将data全部存放于usedSzie中

如果usedSize = 0,那么就相当于把数据全部清空了
上面的写法适用于基本数据类型
如果是引用数据类型,如何使用这个方法?
如果是引用数据类型,那么存储的是地址,这种情况下我们需要遍历这些地址,把他们全部置为空,否则会引起内存泄漏
什么是内存泄漏,简单来说内存泄漏就是我已经不使用某个对象了,但是有个引用数据类型一直在引用这个对象,那么这个对象就不能被回收,因此会一直浪费内存

因为是基本类型所以会报错,把基本类型换为应用类型就不会报错了
顺序表的优点与缺点
- 优点:给定下标的情况下,查询速度非常快 O(1)
- 缺点:如果要删除或增添数据,非常慢 O(N)
三、ArrayList简介
在集合框架中,ArrayList是一个普通的类,实现了List接口,具体框架图如下:

【说明】
- 1. ArrayList是以泛型方式实现的,使用时必须要先实例化
- 2. ArrayList实现了RandomAccess接口,表明ArrayList支持随机访问
- 3. ArrayList实现了Cloneable接口,表明ArrayList是可以clone的
- 4. ArrayList实现了Serializable接口,表明ArrayList是支持序列化的
- 5. 和Vector不同,ArrayList不是线程安全的,在单线程下可以使用,在多线程中可以选择Vector或者CopyOnWriteArrayList
- 6. ArrayList底层是一段连续的空间,并且可以动态扩容,是一个动态类型的顺序表
四、ArrayList的使用
ArrayList的构造

ArrayList常见方法

ArrayList常用遍历方法

可大致分为
for for-each Interator迭代器
其中Interator可以延伸出其他用法,ListInterator是Interator用法的延伸
二维数组


总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
