一、动态数组简介
- 普通数组的局限性
一般我们运用的普通数组是固定大小的,长度在定义时就已经决定,后期不可更改。不可超出范围存储数据。
int[] a = new int[10];
2.动态数组
动态数组是指在声明时没有确定数组大小的数组,后期可根据需要改变长度。除此之外,还需要配备一些基本功能:
- 添加元素
- 删除元素
- (按索引或值)查找元素
此外,这里实现的动态数组需要可以装入各种类型的元素,我们需要用到泛型
- 泛型
在声明某些类时,可以用T(随便一个字母)代表任意类型。这里的类型不能是基本类型(int,double等),而是引用类型(类、数组、包装类等)。就相当于一个类模板,用<>表示。比如给T指派一个Integer类型,那这个类中所有T类型都是Integer类型。比如:
public class Test<T> {
T a;
Test(T data) {
a = data;
System.out.println(a instanceof Integer);
System.out.println(a instanceof String);
}
public static void main(String[] args) {
new Test<Integer>(100);
}
}
输出结果为:
二、动态数组的基本实现:
-
基本属性
这个类中包含length表示当前数组的容量,size表明当前数组的大小,那如何声明数组呢?这个数组要能包含所有的类型,想到Object类是所有类的父类,所以声明一个Object[]的数组,当元素存进去时,元素类型会自动转型成Object类。 -
初始化:
利用构造方法来初始化。无参的方法用来初始化默认长度(10)大小的数组,含参的方法利用参数值来确定初始化大小
//构造方法
public ArrayList() {
length = 10;
arr = new Object[length];
size = 0;
}
public ArrayList(int length) {
this.length = length;
arr = new Object[length];
size = 0;
}
- 添加元素
在添加前需要判断数组是否满,满了需要扩容。扩容时,声明一个新长度大小的数组,把原数组数据逐个复制到新数组上,再将原数组的引用指向新数组即可。
public void add(T element) {
//先判断是否满了
if (size >= arr.length) {
length *= 1.5;
Object[] newarr = new Object[length];
for (int i = 0; i < size; i++) {
newarr[i] = arr[i];
}
arr = newarr;
}
arr[size++] = element;
}
- 删除元素
这里重载了两种方法。一种是按值删除,一种是按索引删除。删除后,需要吧后面的元素往前移动。
public void delete(T element) {
int i = 0;
for (i = 0; i < size; i++) {
if (element == arr[i]) {
while (i < size - 1)
arr[i] = arr[i + 1];
size--;
}
}
}
public void delete(int theIndex) {//索引从0开始
for (int i = theIndex; i < size - 1; i++) {
arr[i] = arr[i + 1];
}
size--;
}
- 查找元素
这里也重载了两种方法。
public Object find(int theIndex) { //按索引查找
return arr[theIndex];
}
public int[] find(T element,int index[]) { //按元素查找,返回下标数组
int j = 0;
for (int i = 0; i < size; i++) {
if (arr[i] == element) {
index[j++] = i;
}
}
return index;
}
- 替换元素
也是两种替换方法重载
public void change(T oldElement, T newElement) { //把所有的旧的数据换成新的
for (int i = 0; i < size; i++) {
if (arr[i] == oldElement) {
arr[i] = newElement;
}
}
}
public void change(int theIndex, T newElement) { //某一索引元素换成新的
arr[theIndex] = newElement;
}
- 数组合并
创建两个数组容量之和的新数组,把第一个数组合第二个数组值先后逐个复制上去。
public void mergeList(ArrayList<T> L) { //二表合并
int newLength = this.length + L.length;
int newSize = this.size + L.size;
Object[] newarr = new Object[newLength];
for (int i = 0; i < size; i++) {
newarr[i] = arr[i];
}
this.arr = newarr;
for (int j = 0; j < L.size; j++) {
this.arr[this.size + j] = L.arr[j];
System.out.println(this.size);
}
this.size = newSize;
this.length = newLength;
}
完整类如下:
public class ArrayList<T> {
int size;
int length;
Object[] arr;
//构造方法
public ArrayList() {
length = 10;
arr = new Object[length];
size = 0;
}
public ArrayList(int length) {
this.length = length;
arr = new Object[length];
size = 0;
}
//添加元素
public void add(T element) {
//先判断是否满了
if (size >= arr.length) {
length *= 1.5;
Object[] newarr = new Object[length];
for (int i = 0; i < size; i++) {
newarr[i] = arr[i];
}
arr = newarr;
}
arr[size++] = element;
}
public void delete(T element) {
int i = 0;
for (i = 0; i < size; i++) {
if (element == arr[i]) {
while (i < size - 1)
arr[i] = arr[i + 1];
size--;
}
}
}
public void delete(int theIndex) {//索引从0开始
for (int i = theIndex; i < size - 1; i++) {
arr[i] = arr[i + 1];
}
size--;
}
public Object find(int theIndex) { //按索引查找
return arr[theIndex];
}
public int[] find(T element,int index[]) { //按元素查找,返回下标数组
int j = 0;
for (int i = 0; i < size; i++) {
if (arr[i] == element) {
index[j++] = i;
}
}
return index;
}
public void change(T oldElement, T newElement) { //把所有的旧的数据换成新的
for (int i = 0; i < size; i++) {
if (arr[i] == oldElement) {
arr[i] = newElement;
}
}
}
public void change(int theIndex, T newElement) { //某一索引元素换成新的
arr[theIndex] = newElement;
}
public void mergeList(ArrayList<T> L) { //二表合并
int newLength = this.length + L.length;
int newSize = this.size + L.size;
Object[] newarr = new Object[newLength];
for (int i = 0; i < size; i++) {
newarr[i] = arr[i];
}
this.arr = newarr;
for (int j = 0; j < L.size; j++) {
this.arr[this.size + j] = L.arr[j];
System.out.println(this.size);
}
this.size = newSize;
this.length = newLength;
}
public void print() {
for (int i = 0; i < size; i++) {
System.out.print(this.arr[i] + " ");
}
System.out.println();
}
}