(十二)对象数组以及Vector类实现

数组的定义

数组是n(n≥1)个相同数据类型的数据元素a0,a1,a2,...,an-1构成的占用一块地址连续的内存单元的有限集合
数组的实现

数组通常以字节为内部计数单位。对一个有n个数据元素的一维数组,设a0是下标为0的数组元素,Loc(a0)是a0的内存单元地址,k是每个数据元素所需的字节个数,则数组中任一数据元素ai的内存单元地址Loc(ai)可由下面公式求出:

  Loc(ai) = Loc(a0) + i × k   ( 0≤i<n ) 


二维数组的顺序存储结构


数组抽象数据类型

数据集合:数组的数据集合可以表示为a0, a1, a2, ..., an-1,且限定数组元素必须存储在地址连续的内存单元中。
操作集合

(1)分配内存空间acclocate():为数组分配用户所需的内存空间。

(2)取数组长度getLength():取数组的长度。

(3)存数组元素set(i,x):把数据元素x存入下标为i的数组中。其约束条件为:0≤i≤getLength()-1。

(4)取数组元素get(i):取出数组中下标为i的数据元素。其约束条件为:0≤i≤getLength()-1。

Java语言支持的数组功能

基本数据类型的数组

     由于数组是非常基础的程序设计语言要素,所以Java语言设计实现了数组功能。Java语言(以及大部分高级程序设计语言)支持的数组操作有:

(1)分配内存空间

(2)获得数组长度

(3)存数组元素

(4)取数组元素

对象数组
    除了可以定义基本数据类型的数组外,Java语言还可以定义 对象数组


//动态对象数组
public class DynamicArray {
    
	final static int defaultSize=10;
	Object[] arr; //对象数组
	int maxSize; //数组的最大长度
	
	//默认的构造方法
	public DynamicArray()
	{
	   init(defaultSize);	
	}
	
	//指定对象数组长度的构造方法
	public DynamicArray(int size)throws Exception
	{
		if(size<=0)
		{
			throw new Exception("数组长度参数异常!");
		}
		init(size);
	}
	
	//根据已有对象数组,拷贝复制生成新的对象数组
	public DynamicArray(DynamicArray a)
	{
	   arr = new Object[a.maxSize];
	   for(int i=0;i<a.maxSize;i++)
	   {
		   arr[i]=a.arr[i];
	   }
	   maxSize = a.maxSize;
	}
	
	
    public void init(int size)
    {
       arr = new Object[size];
       maxSize = size;
    }
    
    //调整对象数组的大小
	public void reSize(int size)throws Exception
	{
		//如果调整的大小<=0,非法!
		if(size<=0)
		{
			throw new Exception("数组长度参数异常!");
		}
		//如果调整的大小与原来相同,则没必要调整,直接返回。
		if(size==maxSize)
			return ;
		//构造一个新的对象数组
		Object[] newArray = new Object[size];
		//判断新调整的大小,比原来大,还是比原来小
		int n=(size > maxSize)? maxSize:size;
		
		for(int i=0;i<n;i++)
		{
		   newArray[i]=arr[i];	
		}
		arr = newArray;
		maxSize = size;
	}
}

向量类

Java语言只直接支持上述基本的数组操作。如果程序开始时定义的数组长度为10,且数组中已经存放了若干数据元素,要在程序运行过程中扩充数组长度为20,且把数组中原先存放的数据元素原样保存,则系统不提供直接支持,需要应用程序自己实现。
为了扩充数组功能,Java类库还定义了Vector类。要说明的是,国内的大部分教材和科技书籍都把Vector类翻译为向量类,但这里的向量和数学上的向量概念完全不同。
向量类Vector扩充了数组的功能,提供了自动扩充数组长度、且把数组中原先存放的数据元素原样保存的功能。Vector类在java.util包中。
集合
集合(Set是具有某种相似特性的事物的全体。换一种说法,也可以说,集合是某种具有相同数据类型的数据元素全体。
如果一个数据元素x在一个集合A中,则说数据元素x属于集合A;如果一个数据元素x不在一个集合A中,就说数据元素x不属于集合A。
如果集合A中的所有数据元素都在集合B中,则说集合B包含集合A。          
集合的运算主要有三种:两个集合的并A∪B、两个集合的交A∩B、两个集合的差A-B。
没有一个数据元素的集合称做空集合。
集合抽象数据类型
数据集合:数据元素集合可以表示为{a0, a1, a2, ..., an-1},每个数据元素的数据类型可以是任意的类类型。
操作集合:

(1)添加add(obj):在集合中添加数据元素obj。

(2)删除remove(obj):删除集合中的数据元素obj。

(3)属于contain(obj):数据元素obj是否属于集合。是则返回true,否则返回false。

(4)包含include(otherSet):当前对象集合是否包含集合otherSet。是则返回true,否则返回false。

(5)相等eqauls(otherSet):当前对象集合是否和集合otherSet相等。是则返回true,否则返回false。

(6)数据元素个数size():返回集合中的数据元素个数。

(7)集合空否isEmpty():若集合空返回true,否则返回false。

集合的特点是数据元素无序且不重复。集合类既可以基于向量类来实现,也可以用其他方法实现。常用的另一种实现方法是基于哈希表来实现。
基于向量类的集合类实现方法:

 1 MyVector类增加的成员函数        

 2 集合类MySet

 3 集合类MySet的测试


public interface Collection {
  
	//在指定位置添加
	public void add(int index,Object element) throws Exception;
	//在集合末端添加
	public void add(Object element) throws Exception;
	//在指定位置设置元素
	public void set(int index,Object element) throws Exception;
    //获得指定位置的元素
	public Object get(int index) throws Exception;
	//获得集合大小
	public int size();
	//在指定位置删除
	public void remove(int index) throws Exception;
	//删除指定对象
	public void remove(Object element) throws Exception;
	//是否包含指定对象
	public boolean contain(Object element) throws Exception;
	
	
}
//用户自定义的Vector类
public class MyVector implements Collection{
    
	private Object[] data; //集合对象数组
	private int count;  //集合大小
	private final static int defaultSize=10;
	
	public MyVector()
	{
	   init(defaultSize);	
		
	}
	
	public MyVector(int size)
	{
		init(size);
	}
	
	public void init(int size)
	{
		data = new Object[size];
		count=0;
	}
	
	//动态扩充内存
	private void ensureCapacity(int minCapacity)
	{
		int oldCapacity = data.length;
		if(minCapacity>oldCapacity)
		{
			Object[] oldData = data;
			int newCapacity = oldCapacity*2;
			if(newCapacity<minCapacity)
			{
				newCapacity = minCapacity;
			}
			data = new Object[newCapacity];
			System.arraycopy(oldData, 0, data, 0, count);
		}
	}
	
	
	@Override
	public void add(int index, Object element) throws Exception {
		// TODO Auto-generated method stub
		if(index>=count+1)
		{
			throw new ArrayIndexOutOfBoundsException(index);
		}
		ensureCapacity(count+1);
		System.arraycopy(data, index, data, index+1, count-index);
		data[index]=element;
		count++;
	}

	@Override
	public void add(Object element) throws Exception {
		// TODO Auto-generated method stub
		add(count);
	}

	@Override
	public boolean contain(Object element) throws Exception {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public Object get(int index) throws Exception {
		// TODO Auto-generated method stub
		if(index>=count||index<0)
		{
		  throw new ArrayIndexOutOfBoundsException(index);
		}
		return data[index];
	}

	@Override
	public void remove(int index) throws Exception {
		// TODO Auto-generated method stub
		if(index>=count||index<0)
		{
		  throw new ArrayIndexOutOfBoundsException(index);
		}
		int j=count-index-1;
		if(j>0)
		{
			System.arraycopy(data, index+1, data, index, j);
		}
		count--;
		data[count]=null;
	}

	private int indexOf(Object element)
	{
		if(element==null)
		{
			for(int i=0;i<count;i++)
			{
				if(data[i]==null)
					return i;
			}
		}
		else
		{
			for(int i=0;i<count;i++)
			{
				if(data[i].equals(element))
					return i;
			}
		}
		return -1;
	}
	
	@Override
	public void remove(Object element) throws Exception {
		// TODO Auto-generated method stub
		int index = indexOf(element);
		if(index>=0)
		{
			remove(index);
		}
	}

	@Override
	public void set(int index, Object element) throws Exception {
		// TODO Auto-generated method stub
		if(index>=count||index<0)
		{
		  throw new ArrayIndexOutOfBoundsException(index);
		}
		data[index]=element;
	}

	@Override
	public int size() {
		// TODO Auto-generated method stub
		return count;
	}

	
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值