一,创建一个带泛型的顺序表的类MyList
1,泛型:泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。
java 中泛型标记符:
E - Element (在集合中使用,因为集合中存放的是元素)
T - Type(Java 类)
K - Key(键)
V - Value(值)
N - Number(数值类型)
? - 表示不确定的 java 类型
2,定义属性
需要定义长度为0的数组values,存储元素的个数size,数组当前长度length,默认最大容量DEFAULT_LENGTH。
public class MyList<A> {
//定义属性
private Object[] values = {};//长度为零的数组
private int size;//当下坐标,当前存储的元素个数
private int length;//表示数组当前的长度 最大容器
private static final int DEFAULT_LENGTH = 10;//默认最大容量
}
二,构造方法
1,顺序表初始化
传入参数为顺序表长度,如果传入长度小于0,报错,如果传入长度小于等于10,就用默认属性初始化,大于10就用传入长度初始化。
public MyList (int initiallength){
if (initiallength <= 0){
throw new IllegalArgumentException("initiallength 不能小于0");
}
if (initiallength <= 10){
length = DEFAULT_LENGTH;
values = new Object[length];
size=0;
}
else{
length = initiallength;
values = new Object[length];
size=0;
}
}
2,添加元素
传入参数为添加元素,如果顺序表还有空直接添加,如果满了需要进行扩容。
扩容:以前的长度设为oldLength,定义新长度为原来的1.5倍,令以前的长度为新长度,定义一个新数组newvalues,通过循环把之前数组里的元素存进新数组里,让初始化数组values等于新数组,再把新数组清空就完成了数组扩容。
移位运算符:在Java中>、>>的区别:>表示大于,如:if(a>b)...结果是boolean类型>>表示右移,如:int i=15; i>>2的结果是3,移出的部分将被抛弃。转为二进制的形式可能更好理解,0000 1111(15)右移2位的结果是0000 0011(3),0001 1010(18)右移3位的结果是0000 0011(3)。
//添加
public void add(A e){
//扩容
if(size == length){
grow();
}
values[size++]=e;
}
public void grow(){
int oldLength = length;
int newLength = oldLength + (oldLength >>1);//1.5倍
length = newLength;
Object[] newvalues = new Object[length];
for (int i = 0;i<oldLength;i++){
newvalues[i] = values[i];
}
//替换引用
values = newvalues;
newvalues=null;
System.out.println("原始容量:"+oldLength+"新增容量:"+newLength);
}
3,根据索引查找元素
传入参数为需要查找的索引,在范围内返回索引对应元素,不在范围报错。
public A get(int index){
// 先检查
if(index>=0&&index<size){
return (A) values[index];
}else{
throw new ArrayIndexOutOfBoundsException("index 超过了范围 max:"+(size-1));
}
}
4,根据元素查找
传入参数为查找元素,循环顺序表判断元素是否相等,返回true或false。
//根据元素查询
//有还是没有
public boolean Get(Object e) {
for (int i = 0; i < length; i++) {
if (values[i] == e || values[i].equals(e)) {
return true;
}
}
return false;
}
5,查找一段元素
传入第一个元素和最后一个元素的索引,超出范围报错,在范围内则遍历输出。
//获取一段
public void getAll(int index,int last){
if(index<0||last<0||index>size-1||last>size-1){
throw new ArrayIndexOutOfBoundsException("index或last 超过了范围");
}else {
for (int i = index; i <= last; i++) {
System.out.println(values[i]);
}
}
}
6,根据索引删除元素
传入删除元素的索引,不在范围内报错,在范围内索引对应元素令为空,通过循环前移索引后的元素。
//检查范围
//将对应位置的元素 设置为null
//后置数据前移一位
//返回移除的元素对象
public A remove(int index){
if(index<0||index>size-1){
throw new ArrayIndexOutOfBoundsException("index 超过了范围 max:"+(size-1));
}else{
values[index]=null;
for(int i=index;i<size;i++){
values[i]=values[i+1];
}
}
return null;
}
7,删除所有相同元素
传入需要删除的元素,通过循环找到相等的元素,令为空,前移后面的元素。
//找到所有的对象所在的下标位置
//分别清除之后 数据移动位置
public Object Remove(Object e){
for(int i=0;i<size;i++){
if(values[i]==e){
values[i]=null;
for( int x=i ;x<size;x++){
values[x]=values[x+1];
}
}
}
return true;
}
8,根据索引移除一段
传入删除一段的第一个元素索引和最后一个元素索引,不在范围报错,在范围最后一个元素索引后的元素前移。
public void removeAll(int index,int last){
if(index<0||last<0||index>size-1||last>size-1){
throw new ArrayIndexOutOfBoundsException("index或last 超过了范围");
}else{
int n = 1;
for (int y=index ;y<size ;y++ ){
values[y]=values[last+n];
n++;
}
size -= (last-index)+1;
}
}
9,添加数组
传入一个数组,循环去除里面的元素依次添加,有空直接添加,没空先扩容再添加。
三,完整代码
public class MyList<A> {
//定义属性
private Object[] values = {};//长度为零的数组
private int size;//当下坐标,当前存储的元素个数
private int length;//表示数组当前的长度 最大容器
private static final int DEFAULT_LENGTH = 10;//默认最大容量
//构造方法
public MyList (int initiallength){
if (initiallength <= 0){
throw new IllegalArgumentException("initiallength 不能小于0");
}
if (initiallength <= 10){
length = DEFAULT_LENGTH;
values = new Object[length];
size=0;
}
else{
length = initiallength;
values = new Object[length];
size=0;
}
}
//添加
public void add(A e){
//扩容
if(size == length){
grow();
}
values[size++]=e;
}
public void grow(){
int oldLength = length;
int newLength = oldLength + (oldLength >>1);//1.5倍
length = newLength;
Object[] newvalues = new Object[length];
for (int i = 0;i<oldLength;i++){
newvalues[i] = values[i];
}
//替换引用
values = newvalues;
newvalues=null;
System.out.println("原始容量:"+oldLength+"新增容量:"+newLength);
}
public A get(int index){
// 先检查
if(index>=0&&index<size){
return (A) values[index];
}else{
throw new ArrayIndexOutOfBoundsException("index 超过了范围 max:"+(size-1));
}
}
//根据元素查询
//有还是没有
public boolean Get(Object e) {
for (int i = 0; i < length; i++) {
if (values[i] == e || values[i].equals(e)) {
return true;
}
}
return false;
}
//获取一段
public void getAll(int index,int last){
if(index<0||last<0||index>size-1||last>size-1){
throw new ArrayIndexOutOfBoundsException("index或last 超过了范围");
}else {
for (int i = index; i <= last; i++) {
System.out.println(values[i]);
}
}
}
//检查范围
//将对应位置的元素 设置为null
//后置数据前移一位
//返回移除的元素对象
public A remove(int index){
if(index<0||index>size-1){
throw new ArrayIndexOutOfBoundsException("index 超过了范围 max:"+(size-1));
}else{
values[index]=null;
for(int i=index;i<size;i++){
values[i]=values[i+1];
}
}
return null;
}
//找到所有的对象所在的下标位置
//分别清除之后 数据移动位置
public Object Remove(Object e){
for(int i=0;i<size;i++){
if(values[i]==e){
values[i]=null;
for( int x=i ;x<size;x++){
values[x]=values[x+1];
}
}
}
return true;
}
public void removeAll(int index,int last){
if(index<0||last<0||index>size-1||last>size-1){
throw new ArrayIndexOutOfBoundsException("index或last 超过了范围");
}else{
int n = 1;
for (int y=index ;y<size ;y++ ){
values[y]=values[last+n];
n++;
}
size -= (last-index)+1;
}
}
public void addAll(Object[] objArr){
if(objArr.length < length-size){
for (int i = 0; i < objArr.length; i++) {
add ((A) objArr[i]);
}
}else{
grow ();
addAll (objArr);
}
}
public static void main(String[] args){
MyList<Integer> myList = new MyList(50);
System.out.println("----------MyList----------");
long Start = System.currentTimeMillis ();
for (int i =0;i<500000;i++){
myList.add(i);
}
long End = System.currentTimeMillis ();
System.out.println ("存储50万组数据- 耗时:"+(End-Start));
Start = System.currentTimeMillis ();
for (int i = 1; i < 5000;i++) {
Integer integer = myList.get (i);
}
End = System.currentTimeMillis ();
System.out.println ("查询多个数据- 耗时:"+(End-Start));
Start = System.currentTimeMillis ();
for (int i = 1; i < 5000;i++) {
Integer integer = myList.remove(i);
}
End = System.currentTimeMillis ();
System.out.println ("移除多个数据- 耗时:"+(End-Start));
}
}