概述
数组基础
数组作为数据结构最大的优点在于可以快速查询,arr[2]。但由于数组的大小在开始创建时就被定义,因此如果存储的内容超出了数组容量,就无法在原先的数组中保存数据。这里就需要使用一个可以动态改变数组容量的动态数组来存放数组。而在建立动态数组类前,我们首先要创建一个数组类。
这里我们假设要创建一个int类型的数组类。在开头先定义好我们这个类中有一个数组data[],以及数组中实际存放的元素数量size。初始化数组类时需要输入数组的容量capacity的值,如果没有输入则默认为10。
public class Array {
private int[] data;
private int size;
public Array(int capacity) {
this.data = new int[capacity];
size = 0;
}
public Array() {
this(10);
}
}
然后我们需要给该数组类添加增删改查四个基础功能。
首先是加的功能,参数index是要添加的位置,即数组的索引,参数element是要添加进去的元素。类似于插入的过程使得整个数组在index往后的索引值都需要往后移一位。
//添加指定索引index位置的元素data
public void add(int index, int element) {
if (size == data.length) {
throw new IllegalArgumentException("Add failed, Array is full");
}
if (index > size || index < 0) {
throw new IllegalArgumentException("Add failed, index is not under[0 - size]");
}
for (int i = size; i > index; i--) {
data[i] = data[i - 1];
}
data[index] = element;
size++;
}
我们可以通过上述的方法封装好在数组首部和尾部添加元素的方法。
public void addFirst(int element) {
add(0, element);
}
public void addLast(int element) {
add(size, element);
}
删除的方法与增加的方法类似,只不过是后续的元素要往前移一位。
//删除index位置的元素并返回该元素的值
public int delete(int index) {
if (index >= size || index < 0) {
throw new IllegalArgumentException("delete failed, index is illegal");
}
int ret = data[index];
for (int i = index; i < size; i++) {
data[i] = data[i + 1];
}
size--;
return ret;
}
public int deleteFirst() {
return delete(0);
}
public int deleteLast() {
return delete(size - 1);
}
查找和改变的方式比较简单。
//寻找数组是否包含元素e,如果包含返回索引值,否则返回-1
public int findx(int e) {
for (int i = 0; i < size; i++) {
if (data[i] == e) {
return i;
}
}
return -1;
}
//将索引上的值改变为e
public void set(int index, int e) {
if (index >= size || index < 0) {
throw new IllegalArgumentException("set failed, index is illegal");
}
data[index] = e;
}
该数组类应该要有个输出,重写Object的toString方法
@Override
public String toString() {
StringBuilder res = new StringBuilder();
res.append("Array: size = %d capacity = %dn", 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();
}
泛型
由于数组不可能永远都是int类型,因此写一个泛型的数组类是必要的,我们可以通过它来创建各个类型的数组。
但是需要注意的是,使用泛型创造的数据结构不可以放置基本数据类型(int, char, boolean, double…),只能放置它们的包装类(Int, Char, Boolean, Double…)。
下面的代码是使用泛型创造的数组类:
需要注意,泛型定义数组时不可以直接new一个泛型数组,而是要new Object[]后再整形成泛型
public class Array<E> {
private E[] data;
private int size;
public Array(int capacity) {
this.data = (E[]) new Object[capacity];
size = 0;
}
public Array() {
this(10);
}
//添加指定索引index位置的元素data
public void add(int index, E element) {
if (size == data.length) {
throw new IllegalArgumentException("Add failed, Array is full");
}
if (index > size || index < 0) {
throw new IllegalArgumentException("Add failed, index is not under[0 - size]");
}
for (int i = size; i > index; i--) {
data[i] = data[i - 1];
}
data[index] = element;
size++;
}
public void addFirst(E element) {
add(0, element);
}
public void addLast(E element) {
add(size, element);
}
//删除index位置的元素并返回该元素的值
public E delete(int index) {
if (index >= size || index < 0) {
throw new IllegalArgumentException("delete failed, index is illegal");
}
E ret = data[index];
for (int i = index; i < size; i++) {
data[i] = data[i + 1];
}
size--;
return ret;
}
public E deleteFirst() {
return delete(0);
}
public E deleteLast() {
return delete(size - 1);
}
//寻找数组是否包含元素e,如果包含返回索引值,否则返回-1
public int findx(E e) {
for (int i = 0; i < size; i++) {
if (data[i] == e) {
return i;
}
}
return -1;
}
//将索引上的值改变为e
public void set(int index, E e) {
if (index >= size || index < 0) {
throw new IllegalArgumentException("set failed, index is illegal");
}
data[index] = e;
}
@Override
public String toString() {
StringBuilder res = new StringBuilder();
res.append("Array: size = %d capacity = %dn", 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();
}
}
动态数组
动态数组要实现的功能是在数组突破容量时扩大数组的容量,当数组实际存储的元素数远小于容量时缩小数组的容量。方法可以是:当数组到极限时,创建一个两倍于原数组容量的新数组,将原数组的内容复制到新数组中,并返回新数组;当数组的size小于等于1/4容量时,创建一个1/2容量的新数组,赋值进去并返回新数组。具体的代码操作只需要改变add和delete两个函数方法。
public void add(int index, E element) {
if (size == data.length) {
renew(data.length * 2);
}
if (index > size || index < 0) {
throw new IllegalArgumentException("Add failed, index is not under[0 - size]");
}
for (int i = size; i > index; i--) {
data[i] = data[i - 1];
}
data[index] = element;
size++;
}
public E delete(int index) {
if (index >= size || index < 0) {
throw new IllegalArgumentException("delete failed, index is illegal");
}
E ret = data[index];
for (int i = index; i < size; i++) {
data[i] = data[i + 1];
}
size--;
if (size == data.length / 4 && data.length / 2 != 0) {
renew(data.length/2);
}
return ret;
}
private void renew(int capacity) {
E[] dataNew = (E[]) new Object[capacity];
for (int i = 0; i < size; i++) {
dataNew[i] = data[i];
}
data = dataNew;
}
代码测试
增加元素观察是否能扩展数组容量,减少很多元素观察是否能缩小容量
public class Main {
public static void main(String[] args) {
Array<Integer> arr = new Array<>();
for(int i = 0 ; i < 10 ; i ++)
arr.addLast(i);
System.out.println(arr);
arr.add(1, 100);
System.out.println(arr);
arr.addFirst(-1);
System.out.println(arr);
arr.delete(2);
System.out.println(arr);
arr.delete(4);
System.out.println(arr);
arr.deleteFirst();
System.out.println(arr);
arr.deleteFirst();arr.deleteFirst();arr.deleteFirst();arr.deleteFirst();arr.deleteFirst();
System.out.println(arr);
}
}
最后
以上就是天真保温杯为你收集整理的如何使用Java构建一个动态数组类数组基础泛型动态数组代码测试的全部内容,希望文章能够帮你解决如何使用Java构建一个动态数组类数组基础泛型动态数组代码测试所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复