数组
数组是一种用于存储多个相同类型数据的容器,数组可以有序的存储数据,每个元素都可以通过一个索引下 标访问,下标通常是从0开始,往后依次递增1 ,最大的下标是长度-1
数组的特点
- 固定大小:数组在创建时必须指定大小,创建后其大小不可改变 - 相同类型:数组中的所有元素必须是相同的数据类型(如整数、字符串等) - 连续存储:数组在内存中占用连续的存储空间 - 索引访问:数组中的每个元素都有一个索引,通过索引可以快速访问元素
动态数组类
属性
-底层用于存储的结构:Object类
-数组的长度
-当前存储元素个数与空位置下标
-初始化的默认长度
方法
-构造方法初始化
-获取元素个数 size()
-判断数组是否为空 isEmpty()
-末尾添加 add(Object E)
-获取数组指定下标元素 get(int index)
-删除指定下标元素或删除指定元素 remove(int index) remove(Object E)
-替换指定下标元素或替换指定元素为新元素 replace(int index, Object e) replace(Object oldE, Object newE)
具体实现
需要掌握的部分知识
-动态数组的扩容
当存入新数据时数组空间不足,数组应当自动扩容,确保数据可以完整存入
if(size == length){ //判断是否需要扩容
int oldLen = length;
int newLen = oldLen + (oldLen >> 1); //1.5倍 向右位移一位 等于整除2
Object[] newArr = new Object[newLen];
for (int i = 0; i < oldLen; i++) {
newArr[i] = values[i];
}
values = newArr;
length = newLen;
System.out.println("扩容完成:" + length);
}
主体及其构造函数
public class MyArrayList {
Object[] values;
int length;//数组长度
int size;//当前数组元素个数
final int def_len = 10;//默认初始长度为10
public MyArrayList() {
length = def_len;
values = new Object[length];
size = 0;
}
public MyArrayList(int initCap) {
if (initCap < 2) {
System.out.println("输入的容量不小于1");
return;
}
length = initCap;
values = new Object[length];
size = 0;
}
}
几种方法的实现
-添加(add)
public void add(Object e){
if (size == length){ //扩容
int oldLen = length;
int newLen = oldLen + (oldLen >> 1);
Object[] newArr = new Object[newLen];
for (int i = 0; i < oldLen; i++) {
newArr[i] = values[i];
}
values = newArr;
length = newLen;
System.out.println("扩容完成");
}
values[size] = e;
size++;
}
public void addAll(Object[] es){
if (size + es.length >= length){
int oldLen = length + es.length;
int newLen = oldLen + (oldLen >> 1);
Object[] newArr = new Object[newLen];
for (int i = 0; i < length; i++) {
newArr[i] = values[i];
}
values = newArr;
length = newLen;
System.out.println("扩容完成");
}
int t = 0;
for (int i = size; i < size + es.length; i++) {
values[i] = es[t];
t++;
}
size = size + es.length;
}
-删除(remove)
public Object remove(int index){//输入要删除的下标
if (index < 0 || index >= size){
System.out.println("输入的下标越界");
}
Object temp = values[index];
for (int i = index; i < size - 1; i++) {
values[i] = values[i + 1];
}
values[size - 1] = null;//可以不写,因为size减小会自动删除
size--;
return temp;
}
public void remove(int si , int ei){
if (si < 0 || ei >= size){
System.out.println("输入的下标越界");
}
if (size - ei >= ei - si){
for (int i = si; i < size; i++) {
values[i] = values[i + ei - si + 1];
}
}else {
for (int i = 0; i < size - ei; i++) {
values[si] = values[ei + 1];
}
}
for (int i = 0; i < size - ei + 1; i++) {
values[size - i] = "";
}
size = size - (ei - si + 1);
}
批量删除还有另一种思路:用一个int n 来记录已删除的元素个数,在遍历的同时就进行数据前移,此时只需一次遍历即可完成
public void remove(Object o){
int n = 0;
for (int i = 0; i < size; i++) {
if (values[i].equals(o)){
n++;
}else {
values[i - n] = values[i];
}
}
if (n == 0){
System.out.println("不存在该元素");
}
size = size - n;
}
-替换(replace)
public void replace(Object oldE, Object newE) {
for (int i = 0; i < size; i++) {
if (values[i].equals(oldE)){//注意要用equals()
values[i] = newE;
//return; //加return则是只替换第一个oldE
}
}
}
-插入(set)
public void set(int index, Object e) {
if (size == length){ //扩容
int oldLen = length;
int newLen = oldLen + (oldLen >> 1);
Object[] newArr = new Object[newLen];
for (int i = 0; i < oldLen; i++) {
newArr[i] = values[i];
}
values = newArr;
length = newLen;
System.out.println("扩容完成");
}
Object[] tempList = new Object[length];//这里将index之前(包括index)的元素取出
for (int i = 0; i <= index; i++) {
tempList[i] = values[i];
}
tempList[index + 1] = e; //单独插入
for (int i = index + 1; i < size; i++) { //再将后续加入
tempList[i + 1] = values[i];
}
values = tempList; //替换
size++;
}