在了解顺序表之前我们要先了解什么是线性表,线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列…
线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储
顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改
接下来我们要实现一些方法来对数组进行增删查改等操作
创建一个类:
public class MyArrayList {
//数组
public int[] elem;
//数组中的元素个数
public int usedSize;
//当前数组默认的容量
public static final int DEFAULT_CAPACITY = 5;
public MyArrayList() {
elem = new int[DEFAULT_CAPACITY];
}
}
public void display() {
for (int i = 0; i < usedSize; i++) {
System.out.print(elem[i]+" ");
}
System.out.println();
}
增加元素默认是在数组的最后位置增加元素
在增加元素之前我们要先判断数组是否满了
判读数组是否满:
public boolean isFull() {
return usedSize == elem.length;
}
增加元素:
public void add(int data) {
if(isFull()) {
//满了进行扩容
elem = Arrays.copyOf(elem,2*elem.length);
}
elem[usedSize] = data;
usedSize++;
}
测试:
public class Test {
public static void main(String[] args) {
MyArrayList myArray = new MyArrayList();
myArray.add(10);
myArray.add(20);
myArray.add(30);
myArray.add(40);
myArray.display();
}
}
注意:这里的增加元素要保证位置的合法性不能小于0,也不能大于数组的长度,更不能间隔着插入,即插入的位置前面一定要有元素;同时插入时其余元素要后移;如果不合法就抛一个异常
同样增加元素之前我们要判断数组是否满了
位置是否合法:
private void checkPosOfAdd(int pos) {
if(pos < 0||pos > usedSize) {
throw new PosException("pos位置不合法:"+pos);
}
}
任意位置增加元素:
public void add(int pos, int data) {
//判断位置是否合法
checkPosOfAdd(pos);
if(isFull()) {
elem = Arrays.copyOf(elem,2*elem.length);
}
for (int i = usedSize - 1; i >= pos; i--) {
elem[i+1] = elem[i];
}
elem[pos] = data;
usedSize++;
}
测试:
public class Test {
public static void main(String[] args) {
MyArrayList myArray = new MyArrayList();
myArray.add(10);
myArray.add(20);
myArray.add(30);
myArray.add(40);
myArray.add(1,15);
myArray.display();
}
}
遍历数组判断是否与这个元素相同:
public boolean contains(int toFind) {
for (int i = 0; i < usedSize; i++) {
if(elem[i] == toFind) {
return true;
}
}
return false;
}
测试:
public class Test {
public static void main(String[] args) {
MyArrayList myArray = new MyArrayList();
myArray.add(10);
myArray.add(20);
myArray.add(30);
myArray.add(40);
System.out.println(myArray.contains(20));
System.out.println(myArray.contains(200));
}
}
遍历这个数组找与要查找的元素是否相同,相同返回该元素的下标,不同返回-1:
public boolean indexOf(int toFind) {
for (int i = 0; i < usedSize; i++) {
if(elem[i] == toFind) {
return i;
}
}
return -1;
}
测试:
public class Test {
public static void main(String[] args) {
MyArrayList myArray = new MyArrayList();
myArray.add(10);
myArray.add(20);
myArray.add(30);
myArray.add(40);
System.out.println(myArray.indexOf(20));
System.out.println(myArray.indexOf(200));
}
}
同样我们要判断该位置是否合法,还有要判断顺序表是否为空,两个条件都合法时返回该位置的元素
顺序表是否为空:
public boolean isEmpty() {
return usedSize == 0;
}
获取任意位置的元素:
public int get(int pos) {
//判断该位置是否合法
checkPosOfAdd(pos);
if(isEmpty()) {
throw new EmptyException("顺序表为空");
}
return elem[pos];
}
测试:
public class Test {
public static void main(String[] args) {
MyArrayList myArray = new MyArrayList();
myArray.add(10);
myArray.add(20);
myArray.add(30);
myArray.add(40);
System.out.println(myArray.get(1));
}
}
与获取任意位置的元素方法相同,要判断该位置是否合法,还要判断顺序表是否为空
将任意位置的元素设为value:
public void set(int pos, int value) {
//判断位置是否合法
checkPosOfAdd(pos);
if(isEmpty()) {
throw new EmptyException("顺序表为空");
}
this.elem[pos] = value;
}
测试:
public class Test {
public static void main(String[] args) {
MyArrayList myArray = new MyArrayList();
myArray.add(10);
myArray.add(20);
myArray.add(30);
myArray.add(40);
myArray.set(1,15);
myArray.display();
}
}
在进行删除操作时要判断顺序表是否为空,找到要删除元素的下标,最后
挪动数据
删除操作:
public void remove(int toRemove) {
if(isEmpty()) {
throw new EmptyException("顺序表为空");
}
int ret = indexOf(toRemove);
for (int i = ret; i < usedSize; i++) {
elem[i] = elem[i+1];
}
usedSize--;
}
测试:
public class Test {
public static void main(String[] args) {
MyArrayList myArray = new MyArrayList();
myArray.add(10);
myArray.add(20);
myArray.add(30);
myArray.add(40);
myArray.remove(10);
myArray.display();
}
}
public int size() {
return usedSize;
}
测试:
public class Test {
public static void main(String[] args) {
MyArrayList myArray = new MyArrayList();
myArray.add(10);
myArray.add(20);
myArray.add(30);
myArray.add(40);
System.out.println(myArray.size());
}
}
public void clear() {
usedSize = 0;
}
测试:
public class Test {
public static void main(String[] args) {
MyArrayList myArray = new MyArrayList();
myArray.add(10);
myArray.add(20);
myArray.add(30);
myArray.add(40);
myArray.display();
System.out.println("*******");
myArray.clear();
myArray.display();
}
}
在集合框架中,ArrayList是一个普通的类,实现了List接口,具体框架图如下:
1.ArrayList是以泛型方式实现的,使用时必须要先实例化
2.ArrayList实现了RandomAccess接口,表明ArrayList支持随机访问
3.ArrayList实现了Cloneable接口,表明ArrayList是可以clone的
4.ArrayList实现了Serializable接口,表明ArrayList是支持序列化的
5.和Vector不同,ArrayList不是线程安全的,在单线程下可以使用,在多线程中可以选择Vector或者
CopyOnWriteArrayList
6. ArrayList底层是一段连续的空间,并且可以动态扩容,是一个动态类型的顺序表