如何使⽤Java构建⼀个动态数组类
数组基础
数组作为数据结构最⼤的优点在于可以快速查询,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){数组全部赋值为1
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 = %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("]");
String();
}
泛型
由于数组不可能永远都是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 = %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("]");
String();
}
}
动态数组
动态数组要实现的功能是在数组突破容量时扩⼤数组的容量,当数组实际存储的元素数远⼩于容量时缩⼩数组的容量。⽅法可以是:当数组到极限时,创建⼀个两倍于原数组容量的新数组,将原数组的内容复制到新数组中,并返回新数组;当数组的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;
}
代码测试
增加元素观察是否能扩展数组容量,减少很多元素观察是否能缩⼩容量

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。