简单定义
数组是一组相同数据类型元素的集合。
特点
- 定长,初始化后不可动态修改。
- 存储数据类型相同
- 在栈内存里的引用是连续分配的,实际数据分配在堆内存,不是连续分配的。
内存示意图
网上找到一个好图:
申明方式
- 数据类型 [] 数组名称 = new 数据类型[数组长度];
- 数据类型 [] 数组名称 = new 数据类型[]{数组元素1,数组元素2}
- 数据类型 [] 数组名称 = {数组元素1,数组元素2}
数组基本操作
增删改查
package com.array;
import lombok.Data;
/**
* @author gang.tu
* @ClassName BaseArray
*/
@Data
public class BaseArray {
/**
* @description 数组长度
*/
private int length;
private Object[] array;
/**
* @description 实际长度
*/
private int size;
BaseArray(int length) {
this.length = length;
array = new Object[length];
size = 0;
}
/**
* @description 添加元素
* @author gang.tu
* @return: boolean
*/
boolean add(Object value) {
if (size == length) {
return false;
}
array[size++] = value;
return true;
}
/**
* @description 删除元素
* @author gang.tu
* @return: boolean
*/
boolean delete(Object value) {
int index = query(value);
if (index == -1) {
return false;
}
if (index == size - 1) {
array[index] = null;
} else {
for (int i = index; i < size - 1; i++) {
array[i] = array[i + 1];
}
}
size--;
return true;
}
/**
* @description 查询元素
* @author gang.tu
* @return: boolean
*/
int query(Object value) {
if (value == null || size == 0) {
return -1;
}
for (int i = 0; i < size; i++) {
if (value.equals(array[i])) {
return i;
}
}
return -1;
}
/**
* @description 修改元素
* @author gang.tu
* @return: boolean
*/
boolean update(Object oldValue, Object newValue) {
int index = query(oldValue);
if (index == -1) {
return false;
}
array[index] = newValue;
return true;
}
}
单元测试
package com.array;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
/**
1. @author gang.tu
2. @ClassName BaseArrayTest
*/
public class BaseArrayTest {
BaseArray baseArray;
@Before
public void init() {
baseArray = new BaseArray(5);
baseArray.add("A");
}
@Test
public void add() {
Assert.assertTrue(baseArray.getLength() == 5);
Assert.assertTrue(baseArray.getSize() == 1);
baseArray.add("B");
baseArray.add("C");
Assert.assertTrue(baseArray.getLength() == 5);
Assert.assertTrue(baseArray.getSize() == 3);
baseArray.add("D");
Assert.assertTrue(baseArray.getSize() == 4);
}
@Test
public void delete() {
Assert.assertTrue(baseArray.getLength() == 5);
Assert.assertTrue(baseArray.getSize() == 1);
Assert.assertFalse(baseArray.delete("B"));
Assert.assertTrue(baseArray.delete("A"));
Assert.assertTrue(baseArray.getLength() == 5);
Assert.assertTrue(baseArray.getSize() == 0);
}
@Test
public void query() {
Assert.assertTrue(baseArray.query("B") == -1);
Assert.assertTrue(baseArray.query("A") == 0);
}
@Test
public void update() {
Assert.assertFalse(baseArray.update("B", "E"));
Assert.assertTrue(baseArray.query("E") == -1);
Assert.assertTrue(baseArray.update("A", "E"));
Assert.assertTrue(baseArray.query("E") == 0);
}
}
总结
网上看到一段话总结的特别好,借来用用:
数组的局限性分析:
- 插入快,对于无序数组,上面我们实现的数组就是无序的,即元素没有按照从大到小或者某个特定的顺序排列,只是按照插入的顺序排列。无序数组增加一个元素很简单,只需要在数组末尾添加元素即可,但是有序数组却不一定了,它需要在指定的位置插入
- 查找慢,当然如果根据下标来查找是很快的。但是通常我们都是根据元素值来查找,给定一个元素值,对于无序数组,我们需要从数组第一个元素开始遍历,直到找到那个元素。有序数组通过特定的算法查找的速度会比无需数组快,后面我们会讲各种排序算法。
- 删除慢,根据元素值删除,我们要先找到该元素所处的位置,然后将元素后面的值整体向前面移动一个位置。也需要比较多的时间。
- 数组一旦创建后,大小就固定了,不能动态扩展数组的元素个数。如果初始化你给一个很大的数组大小,那会白白浪费内存空间,如果给小了,后面数据个数增加了又添加不进去了。
- 很显然,数组虽然插入快,但是查找和删除都比较慢,而且扩展性差,所以我们一般不会用数组来存储数据,那有没有什么数据结构插入、查找、删除都很快,而且还能动态扩展存储个数大小呢,答案是有的,但是这是建立在很复杂的算法基础上,后面我们也会详细讲解。