开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第17天,点击查看活动详情
数组
- 将数组码成一排进行存放
封装我们自己的数组
public class Array {
private int[] data;
//在data中有多少个有效的元素
private int size;
//构造函数,copacity是用户传入的容量大小,通过传入的copacity构造Array
public Array(int copacity) {
data = new int[copacity];
size = 0;
}
//如果他不知道自己声明的数组需要装多少元素,我们可以让他不用指定
public Array() {
this(10);
}
//获取数组有多少个元素
public int getSize() {
return size;
}
//获取数组的容量大小
public int getCopacity() {
return data.length;
}
//返回数组是否为空
public boolean isEmpty() {
return size == 0;
}
向数组中添加元素
向数组的末尾添加元素,记得维护数组的size
//向数组末尾添加元素
public void addList(int e) {
// 我们要对传入的进行一个判断,是否超过我们数组的长度
if (size == data.length) {
throw new IllegalArgumentException("Array is full");
}
data[size] = e;
size++;
上面两句相当于下面这一句
//data[size++] = e;
}
向指定位置插入元素
数组的索引是从零开始,所以size的指向是下一个空的元素
思路:从最后一个元素(size-1)开始挪动,等露出我们想插入的地方,我们就把元素插入,然后维护数组长度
public void add(int index, int e) {
if (size == data.length) {
throw new IllegalArgumentException("Array is full");
}
// 我们要对用户传入的index判断是否合法
if (index < 0 || index > size) {
throw new IllegalArgumentException("index < 0 || index > size");
}
for (int i = size -1; i >= index; i--) {
data[i + 1] = data[i];
}
data[index] = e;
size ++;
//由于我们写了add方法,那我们上面的数组末尾插入可以修改一下
public void addList(int e) {
add(size, e);
}
// 同理,我们复用一下add方法实现 数组的头部插入元素
public void addFirst(int e) {
add(0,e);
}
查询元素和修改元素
数据是被我们封装在data中的,对于静态数组,我们可以使用传入索引的办法去查找,在我们自定义当中也是可以使用的,对于每一个类都要覆盖父类的一个方法
//查询
@Override
public String toString() {
//拼接一个字符串
StringBuilder res = new StringBuilder();
// 首先String.format初始化,反应我们数组的基本信息
res.append(String.format("Array:size = %d, copacity = %d\n",size,data.length));
res.append("[");
for (int i = 0; i < size; i++) {
res.append(data[i]);
if (i != size - 1) {
res.append(", ");
}
}
res.append("]");
return res.toString();
}
// 获取指定索引index元素
int get(int index) {
if(index < 0 || index > size)
throw new IllegalArgumentException("get is fail.");
return data[index];
}
// 修改index索引的元素
int set(int index,int e) {
if(index < 0 || index > size)
throw new IllegalArgumentException("set is fail.");
return data[index] = e;
}
数组的包含,搜索和删除
一些情况下,数组中有很多元素,我们要查询是否包含了某个元素
// 查询数组中是否含有我们传入的元素
public boolean contains(int e) {
for (int i = 0; i < size; i++) {
if (data[i] == e) {
return true;
}
}
return false;
}
//查找指定元素和索引的位置,如果不存在,返回-1
public int find(int e) {
for (int i = 0; i < size; i++) {
if (data[i] == e) {
// 返回索引
return i;
}
}
return -1;
}
删除指定元素
原理:需要删除的地方,将他的下一个值覆盖掉他的值,后面的依次覆盖前面的值,维护数组的size
// 从数组中删除指定元素,返回删除的元素
public int remove(int index) {
if(index < 0 || index > size){
throw new IllegalArgumentException("get is fail.");}
// 将要被删除的元素存储起来,将来返回给用户
int res = data[index];
for (int i = index + 1; i < size; i++) {
data[i - 1] = data[i];
}
size--;
return res;
}
// 删除第一个元素
public int removeFrist(int index) {
return remove(0);
}
// 删除最后一个元素
public int removeLast(int index) {
return remove(size - 1);
}
// 查看数组中是否有这个元素,并将它删除
public boolean removeElement(int e) {
int index = find(e);
if (index != -1) {
remove(index);
return true;
}
return false;
}
使用泛型
由于我们目前写的只有int类型,我们需要存放任意类型,才能更加实用
- 让数据结构可以放置“任意类型”的数据
- 不可以是基本数据类型,只能是类对象
public class Arraytest<E> {
private E[] data;
//在data中有多少个有效的元素
private int size;
//构造函数,copacity是用户传入的容量大小,通过传入的copacity构造Array
public Arraytest(int copacity) {
data = (E[])new Object[copacity];
size = 0;
}
//如果他不知道自己声明的数组需要装多少元素,我们可以让他不用指定
public Arraytest() {
this(10);
}
//获取数组有多少个元素
public int getSize() {
return size;
}
//获取数组的容量大小
public int getCopacity() {
return data.length;
}
//返回数组是否为空
public boolean isEmpty() {
return size == 0;
}
//向数组末尾添加元素
public void addLast(E e) {
//// 我们要对传入的进行一个判断,是否超过我们数组的长度
// if (size == data.length) {
// throw new IllegalArgumentException("Array is full");
// }
// data[size] = e;
// size++;
add(size, e);
}
// 数组的头部插入元素
public void addFirst(E e) {
add(0, e);
}
//在index的位置插入一个元素e
public void add(int index, E e) {
if (size == data.length) {
throw new IllegalArgumentException("Array is full");
}
// 我们要对用户传入的index判断是否合法
if(index < 0 || index > size)
throw new IllegalArgumentException("Add failed. Require index >= 0 and index <= size.");
for (int i = size -1; i >= index; i--) {
data[i + 1] = data[i];
}
data[index] = e;
size ++;
}
// 获取指定索引index元素
E get(int index) {
if(index < 0 || index > size)
throw new IllegalArgumentException("get is fail.");
return data[index];
}
// 修改index索引的元素
E set(int index,E e) {
if(index < 0 || index > size)
throw new IllegalArgumentException("set is fail.");
return data[index] = e;
}
//查询
@Override
public String toString() {
//拼接一个字符串
StringBuilder res = new StringBuilder();
// 首先String.format初始化,反应我们数组的基本信息
res.append(String.format("Array:size = %d, copacity = %d\n",size,data.length));
res.append("[");
for (int i = 0; i < size; i++) {
res.append(data[i]);
if (i != size - 1) {
res.append(", ");
}
}
res.append("]");
return res.toString();
}
// 查询数组中是否含有我们传入的元素
public boolean contains(E e) {
for (int i = 0; i < size; i++) {
if (data[i] .equals(e) ) {
return true;
}
}
return false;
}
//查找指定元素和索引的位置,如果不存在,返回-1
public int find(E e) {
for (int i = 0; i < size; i++) {
if (data[i].equals(e)) {
// 返回索引
return i;
}
}
return -1;
}
// 从数组中删除指定元素,返回删除的元素
public E remove(int index) {
if(index < 0 || index > size){
throw new IllegalArgumentException("get is fail.");}
// 将要被删除的元素存储起来,将来返回给用户
E res = data[index];
for (int i = index + 1; i < size; i++) {
data[i - 1] = data[i];
}
size--;
// 删除size指向的引用。java回收机制就能删除对象的引用
// 当我们使用泛型时,数组中存储的时一个一个的引用。当数组中还存在着一个对象的引用的话,就不会被java自动回收机制所回收
data[size] = null;
return res;
}
// 删除第一个元素
public E removeFrist(int index) {
return remove(0);
}
// 删除最后一个元素
public E removeLast(int index) {
return remove(size - 1);
}
// 查看数组中是否有这个元素,并将它删除
public boolean removeElement(E e) {
int index = find(e);
if (index != -1) {
remove(index);
return true;
}
return false;
}
}
动态数组
思路:如果原来的数组满了,我们开辟一个更大的空间,将原来的数组放到我们这个大数组当中
private void resize(int newCapacity) {
强转
E[] newData = (E[])new Object[newCapacity];
for (int i = 0; i < size; i++) {
旧数组进入新数组
newData[i] = data[i];
}
改变指向
data = newData;
}