要求:设计一个泛型类Collection,它存储object对象的集合(在数组中),以及该集合当前的大小。提供public方法isEmpty,makeEmpty,insert,remove,isPresent.方法isPresent(x)当且仅当在集合中存在(由equals定义) 等于x的一个object时返回true
实现如下:
package Algorithm.GenericParadigm;
import java.util.Arrays;
/**
* Created by jiangyayi on 19/6/26.
*
* 要求:设计一个泛型类Collection,它存储object对象的集合(在数组中),
* 以及该集合当前的大小。提供public方法isEmpty,makeEmpty,insert,remove,isPresent.
* 方法isPresent(x)当且仅当在集合中存在(由equals定义) 等于x的一个object时返回true
*
* @param <E>
*/
public class CollectionMaker<E> {
//当数组为空的时候,定义数组
private static final Object[] EMPTY_ELEMENTDATA = {};
//默认的数组大小是10
private static final int DEFAULT_CAPACITY = 16;
//定义数组的最大size=Integer.MAX_VALUE - 8
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
int size;
private Object[] elementData;
public CollectionMaker(Object[] elementData){
this.elementData=elementData;
size=elementData.length;
}
public void setElementData(Object[] elementData) {
this.elementData = elementData;
}
public Object[] getElementData() {
return elementData;
}
public boolean isEmpty() {
return elementData.length==0;
}
public void makeEmpty(){
//相当于list的clear()方法
// clear to let GC do its work
for (int i = 0; i < size; i++)
elementData[i] = null;
size = 0;
}
public boolean insert(E obj){
checkArea(size+1);
elementData[size++]=obj;
return true;
}
//checkArea方法主要是确保elementData数组有足够的空间来存储待添加的元素
//mingCapacity是insert(E e)方法中调用checkArea时传入的size+1的值
public void checkArea(int minCapacity){
if(elementData ==EMPTY_ELEMENTDATA){
minCapacity=Math.max(minCapacity,DEFAULT_CAPACITY);
}
if(minCapacity-size>0){
//如果最小需要大于数组现有大小,调用数组扩容
grow(minCapacity);
}
}
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
//新的数组容量=老的数组长度的1.5倍。oldCapacity >> 1 相当于除以2
int newCapacity = oldCapacity + (oldCapacity >> 1);
//如果新的数组容量newCapacity小于传入的参数要求的最小容量minCapacity,那么新的数组容量以传入的容量参数为准。
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
//如果新的数组容量newCapacity大于数组能容纳的最大元素个数 MAX_ARRAY_SIZE 2^{31}-1-8
//调用hugeCapacity方法
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
//hugeCapacity再判断传入的参数minCapacity是否大于MAX_ARRAY_SIZE,
//如果minCapacity大于MAX_ARRAY_SIZE,那么
//newCapacity等于Integer.MAX_VALUE,否则newCapacity等于MAX_ARRAY_SIZE
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE : MAX_ARRAY_SIZE;
}
/**
* 参照ArrayList的remove方法
public boolean remove(Object o) {
if (o == null) {
for (int index = 0; index < size; index++)
if (elementData[index] == null) {
fastRemove(index);
return true;
}
} else {
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
fastRemove(index);
return true;
}
}
return false;
}
**/
public boolean remove(Object o){
if(o==null){
for (int i=0;i<size;i++){
if (elementData[i]==null){
fastRemove(i);
return true;
}
}
}else {
for (int i=0;i<size;i++) {
if (o.equals(elementData[i])) {
fastRemove(i);
return true;
}
}
}
return false;
}
private void fastRemove(int index) {
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work
}
public boolean isPresent(E x){
boolean isPre=false;
for(int i=0;i<=size-1;i++){
if(elementData.equals(x)){
isPre=true;
}
}
return isPre;
}
}