一般数组在创建后,就决定了数组的大小,就不可以动态的再添加数组元素,而在实际应用中,我们希望这个数组是动态可以添加元素的。
当然,像iOS中会存在NSMutabbleArray这种类型
为了更好的了解动态数组的原理、特性,我们自己来实现一个动态数组
动态数组(Dynamic Array)接口设计
一个动态数组,应该包含一些接口:
int size();//获取元素的数量
bool isEmpty();//数组是否为空
//增删改查
void add(E element);//添加元素到数组最后面
void add(int index, E element);//在index位置添加元素
void remove(int index);//删除index位置上的元素
void clear();//删除所有元素
E set(int index, E element);//更新设置index位置的数据为element
bool contains(E element);//查找是否包含某个元素
E get(int index);//查找index的位置上对应的元素
int indexOf(E element);//查找某个元素所在的位置
一个数组的确定,至少需要两个变量:
int size;//表示数组的实际长度
int [] elements;//数组元素
对象数组
数组里面存放的是 对象(引用类型)
问:一个对象数组,里面的元素存储的是对象内容,还是地址?
比如,Person[] person = new Person[7];
那么,Person[0]里面存储的是什么?
假设Person里面有:
int age;//4
double height;//8
String name[];//4
如果Person[0]里面存储的是每一个实际变量
那也就是,每一个元素里面都有 age、height、name。那么每个元素至少要占16个字节
但是,由于建立数组的时候,是泛型建立的(这样才能保证数组里面放各种不同数据类型的数据),也就是:
Object[] objects = new Object[];
每个元素大小在建立的时候已经确定了,只有4个字节
那,后期怎么会自动扩容到16个字节?
因此,Person[0]里面存储的是地址
这样做也有好处,就是在初创数组的时候,即使写了new Object[7];,其实也只是7个引用的大小内存
在移除最后一个元素的时候,只需要将地址值赋值为null即可
动态数组的实现代码:
注:下面的代码接口名可能与上面的接口名不一样
上面是老师讲的时候的接口名
下面代码的接口名是自己默写的时候,自己想到的
该程序只支持类型为Int的数组,不支持对象数组、泛型等
package com.mj;
public class ArrayList {
//元素的数量
private int size;
//所有元素
private int[] elements;
有个需要注意的地方:
size是数组实际占用的大小
elements.length是数组分配的空间大小
size <= elements.length
//构造函数
public ArrayList()
{
elements = new int[10];
}
//带参的构造函数
public ArrayList(int capaticy)
{
//防止用户输入不正确数字
capaticy = capaticy < 10 ? 10 : capaticy;
elements = new int[capaticy];
}
/**
*获取数组长度
*/
public int size()
{
return size;
}
/**
*数组是否为空
*/
public boolean isEmpty()
{
return size == 0;
}
/**
* 在数组最后面添加一个元素
*/
public boolean add(int element)
{
add(size, element);
return true;
}
/**
* 在location位置上添加element元素,并返回老位置上的数据。这个应该理解为替换,而不是插入
* @param location
* @param element
*/
public int replace(int location, int element)
{
if (location < 0 || location >= size)
{
throw new IndexOutOfBoundsException("您输入的数据有误: Index:"+location+" size:"+size);
}
int old = elements[location];
elements[location] = element;
return old;
}
/**
* 在location位置上添加element元素
* @param location
* @param element
*/
public void add(int location, int element)
{
if (location < 0 || location > size)
{
throw new IndexOutOfBoundsException("您输入的数据有误: Index:"+location+" size:"+size);
}
ensureCapacity(size + 1);
for (int i = size - 1; i >= location; i--) {
elements[i+1] = elements[i];
}
elements[location] = element;
size++;
}
/**
* 扩容
* */
private void ensureCapacity(int capacity)
{
int oldCapacity = elements.length;
if (oldCapacity >= capacity) {
return;
}
int newCapacity = (int)(oldCapacity * 1.5);
//或者
//int newCapacity = oldCapacity + (oldCapacity >> 1);
int[] newElements = new int[newCapacity];
for (int i = 0; i < size; i++) {
newElements[i] = elements[i];
}
elements = newElements;
}
/**
* 删除一个元素,并返回被删除的元素值
*/
public int delete()
{
size--;
return 0;
}
/**
* 删除location位置上的元素,并返回被删除的元素值
*/
public int deleteArray(int location)
{
if (location < 0 || location >= size)
{
throw new IndexOutOfBoundsException("您输入的数据有误: Index:"+location+" size:"+size);
}
//0 1 2 3 4 5 6 下标
//2 4 6 7 9 10 12 数据
//删除下标为3的值
int old = elements[location];
for (int i = location; i < size; i++) {
elements[i] = elements[i + 1];
}
size--;
//最后一个元素不处理也可以
elements[size] = 0;
return old;
}
/**
* 查找location位置上的元素
*/
public int searchElementArray(int location)
{
if (location < 0 || location >= size)
{
throw new IndexOutOfBoundsException("您输入的数据有误: Index:"+location+" size:"+size);
}
return elements[location];
}
/**
* 查找element元素所在的位置
*/
public int searchContainsArray(int element)
{
for (int i = 0; i < size; i++) {
if(elements[i] == element)
{
return i;
}
}
System.out.println("没有找到该元素");
return -1;
}
/**
* 数组清空,所有数组元素为0
*/
public void clearArray()
{
for (int i = 0; i < size; i++) {
elements[i] = 0;
}
size = 0;
}
/**
* 销毁数组,数组不存在
*/
public void destroyArray()
{
size = 0;
}
//数组打印输出
@Override
public String toString()
{
StringBuilder string = new StringBuilder();
string.append("size = ").append(size).append(" [");
for (int i = 0; i < size; i++) {
string.append(elements[i]);
//不是最后一个元素才会加逗号(最后一个元素不加逗号)
if (i != size-1) {
string.append(", ");
}
}
string.append("];");
return string.toString();
}
}
package com.mj;
public class Main {
public static void main(String[] args)
{
ArrayList list = new ArrayList(2);
int listLength = list.size();
System.out.println("数组长度为" + listLength);
list.add(2);
list.add(22);
list.add(32);
list.add(3, 100);
list.searchElementArray(1);
list.add(2);
System.out.println(list.toString());
list.deleteArray(3);
System.out.println(list.toString());
}
}