package ceun.collections;
/**
* 一个子ArrayBag对象是Object的指针构成的集合
* 可以往包中加入任意类型的对象
*/
public class ArrayBag implements Cloneable {
/**
* 存储包的元素
*/
private Object[] data;
/**
* 存储包元素的数目
*/
private int manyItem;
/**
* 初始化空包,初始容量为10。注意,只要没有达到容量的上限, add方法就能有效地执行(不需要额外的内存)。
*
* @postcondition 包是空的,初始容量是10
* @exception OutOfMemoryError
* 表明没有足够的内存用于生成新的Object[10]
*/
public ArrayBag() {
final int INITIAL_CAPACITY = 10;
data = new Object[INITIAL_CAPACITY];
manyItem = 0;
}
/**
* 用指定的初始容量来初始化空包。注意,只要没有达到容量的上限, add方法就能有效地执行(不需要额外的内存)。
*
* @param initialCapacity
* 包的初始容量
* @precondition initialCapacity是非负数。
* @postcondition 生成空包,容量为给定的初始量。
* @exception IllegalArgumentException
* @exception OutOfMemoryError
* 表明没有足够的内存用于生成新的Object[initialCapacity]
*/
public ArrayBag(int initialCapacity) {
if (initialCapacity < 0)
throw new IllegalArgumentException("initialCapacity不能小于0");
data = new Object[initialCapacity];
manyItem = 0;
}
/**
* 将某个对象的指针放入包中。如果新增的对象指针会使得包超出当前的容量, 那么在增加新元素前增加容量。新元素可以是null指针。
*
* @param element
* 增加到包中的元素。
* @postcondition 指定对象的指针被增加到了包中。
* @exception OutOfMemoryError
* 表明没有足够的内存
*/
public void add(Object element) {
if (manyItem == data.length)
ensureCapacity(manyItem * 2 + 1);
data[manyItem] = element;
manyItem++;
}
/**
* 增加另一个包中的内容到当前包中。
*
* @param append
* 一个包,它的内容将被增加到当前包中。
* @precondition append不为空
* @postcondition 将append中的元素增加到了当前包中。
* @exception NullPointerExceptionb
* 表明append为空
* @exception OutOfMemoryError
* 表明没有足够的内存空间来增加包的大小。
*/
public void addAll(ArrayBag append) {
ensureCapacity(manyItem + append.manyItem);
System.arraycopy(append.data, 0, data, manyItem, append.manyItem);
manyItem += append.manyItem;
}
/**
* 生成包含其他两个包的所有元素的新包。
*
* @param b1
* 包一
* @param b2
* 包二
* @precondition b1和b2 都不为null
* @exception NullPointerException
* 表明某个参数为null OutOfMemoryError 表明没有足够的内存空间用于创建新包。
*/
public static ArrayBag union(ArrayBag b1, ArrayBag b2) {
ArrayBag answer = new ArrayBag(b1.getCapacity() + b2.getCapacity());
System.arraycopy(b1.data, 0, answer.data, 0, b1.manyItem);
System.arraycopy(b2.data, 0, answer.data, b1.manyItem, b2.manyItem);
answer.manyItem = b1.manyItem + b2.manyItem;
return answer;
}
/**
* 用于统计包中某个特定元素出现次数的存取方法。
*
* @param target
* 将被统计的Object的指针。
* @return 返回 target在包中出现的次数。如果target 不为null,那么将使用target.equals方法来统计次数。
*/
public int countOccurrences(Object target) {
int answer;
int index;
answer = 0;
if (target == null) {
// 统计包中null出现的次数]
for (index = 0; index < manyItem; index++)
if (data[index] == null)
answer++;
} else {
// 使用target.equals来确定target出现的次数
for (index = 0; index < manyItem; index++)
if (target.equals(data[index]))
answer++;
}
return answer;
}
/**
* 从包中删除某个指定元素的副本。
*
* @param target
* 将从包中移除的某个元素。
* @postcondition 如果在包中找到了target,那么移除该target的一个副本,并且方法返回true,
* 否则包保持不变,方法返回false。注意,如果target不为null,那么使用target.equals方法
* 在包中查找。
*/
public boolean remove(Object target) {
int index;// target在data数组中的位置
if (target == null) {
// 找到包中null指针在包中首次出现
index = 0;
while ((index < manyItem) && (data[index] != null))
index++;
} else {
index = 0;
while ((index < manyItem) && (!target.equals(data[index])))
index++;
}
if (index == manyItem)
return false;
else {
manyItem--;
data[index] = data[manyItem];// 将最后一个元素移到index位置
data[manyItem] = null;
return true;
}
}
/**
* 确保包有足够的容量
*/
public void ensureCapacity(int minimumCapacity) {
Object[] newData;
if (minimumCapacity > data.length) {
newData = new Object[minimumCapacity];
System.arraycopy(data, 0, newData, 0, manyItem);
data = newData;
}
}
/**
* 获得包的容量
*/
public int getCapacity() {
return data.length;
}
/**
* 将包的当前容量减小到与它的当前的大小(即包含的元素个数)相等。
*
* @postcondition 包的容量变成与它的当前大小相同。
* @exception OutOfMemoryError
* 表明没有足够的内存用于容量改变。
*/
public void trimToSize() {
Object[] trimmedArray;
if (data.length != manyItem) {
trimmedArray = new Object[manyItem];
System.arraycopy(data, 0, trimmedArray, 0, manyItem);
data = trimmedArray;
}
}
/**
* 获得包的当前大小
*
* @return 返回包的当前大小
*/
public int size() {
return this.manyItem;
}
/**
* 克隆当前包
*/
public Object clone() {
ArrayBag newBag = null;
try {
newBag = (ArrayBag) super.clone();
} catch (CloneNotSupportedException e) {
throw new RuntimeException(
"This class does not implement Cloneable");
}
newBag.data = (Object[]) data.clone();
return newBag;
}
/**
* 从包中检索某个随机元素的存取方法
* @precondition
* 包不为空
* @return
* 返回从包中任意选定的元素
* @exception IllegalStateException
* 表明包是空的
* */
public Object grab(){
int i;
if(manyItem==0)
throw new IllegalStateException("包是空的");
i=(int)(Math.random()*manyItem);
return data[i];
}
/**
* 打印包的元素
*/
public void printData() {
for (int i = 0; i < manyItem; i++)
System.out.println(data[i]);
}
}
-------------------------------------
测试包
_____________
package ceun.test;
import ceun.collections.ArrayBag;
import junit.framework.TestCase;
public class TestArrayBag extends TestCase {
protected void setUp() throws Exception {
System.out.println("setUp()**********************");
}
protected void tearDown() throws Exception {
System.out.println("tearDown()/n**********************");
}
/*
* “ceun.collections.ArrayBag.add(Object)”的测试方法
*/
public void testAdd() {
System.out.println("testAdd");
ArrayBag b = new ArrayBag();
b.add(new String("Hello ceun!"));
b.add(new Integer(10));
b.add("Good ok");
b.printData();
}
/*
* “ceun.collections.ArrayBag.addAll(ArrayBag)”的测试方法
*/
public void testAddAll() {
System.out.println("testAddAll()");
ArrayBag b1 = new ArrayBag(3);
b1.add(new String("Hello ceun!"));
b1.add(new Integer(10));
b1.add("Good ok");
b1.printData();
System.out.println("--------------------");
ArrayBag b2=new ArrayBag(2);
b2.add("我们");
b2.add("来了");
b2.printData();
System.out.println("--------------------");
b1.addAll(b2);
b1.printData();
}
/*
* “ceun.collections.ArrayBag.union(ArrayBag, ArrayBag)”的测试方法
*/
public void testUnion() {
System.out.println("testAddUnion()");
ArrayBag b1 = new ArrayBag(3);
b1.add(new String("Hello ceun!"));
b1.add(new Integer(10));
b1.add("Good ok");
b1.printData();
System.out.println("--------------------");
ArrayBag b2=new ArrayBag(2);
b2.add("我们");
b2.add("来了");
b2.printData();
System.out.println("union--------------------");
ArrayBag b=ArrayBag.union(b1,b2);
b.printData();
}
/*
* “ceun.collections.ArrayBag.countOccurrences(Object)”的测试方法
*/
public void testCountOccurrences() {
System.out.println("testCountOccurrences()-----");
ArrayBag b = new ArrayBag();
b.add(new String("Hello ceun!"));
b.add(new Integer(10));
b.add(null);
b.add("Good ok");
b.add(null);
b.add(null);
b.add(new Integer(10));
b.add("Good ok");
b.printData();
System.out.println("null出现次数"+b.countOccurrences(null));
}
/*
* “ceun.collections.ArrayBag.remove(Object)”的测试方法
*/
public void testRemove() {
System.out.println("testRemove()-----");
ArrayBag b = new ArrayBag();
b.add(new String("Hello ceun!"));
b.add(new Integer(10));
b.add(null);
b.add("Good ok");
b.add(null);
b.add(null);
b.add(new Integer(10));
b.add("Good ok");
b.printData();
b.remove(null);
System.out.println("remove--------------------");
b.printData();
}
/*
* “ceun.collections.ArrayBag.trimToSize()”的测试方法
*/
public void testTrimToSize() {
System.out.println("testTrimToSize()-----");
ArrayBag b = new ArrayBag();
System.out.println("原容量"+b.getCapacity());
b.add(new String("Hello ceun!"));
b.add(new Integer(10));
b.add(null);
b.add("Good ok");
b.add(null);
b.add(null);
b.add(new Integer(10));
b.printData();
b.trimToSize();
System.out.println("后容量"+b.getCapacity());
b.printData();
}
/*
* “ceun.collections.ArrayBag.clone()”的测试方法
*/
public void testClone() {
System.out.println("testClone()-----");
ArrayBag b = new ArrayBag();
b.add(new String("Hello ceun!"));
b.add(new Integer(10));
b.add(null);
b.add("Good ok");
b.add(null);
b.add(new Integer(10));
b.printData();
ArrayBag cb =(ArrayBag)b.clone();
cb.add("Copy ok");
System.out.println("copy--------------------");
cb.printData();
System.out.println("b--------------------");
b.printData();
}
}