import java.util.Arrays;
public class ListTest {
public static void main(String[] args) {
//创建列表对象
ListArray listArray = new ListArray();
listArray.add("a");
listArray.add("b");
//没有重写toString()方法,只能调用原始的Object方法输出地址
listArray.add(0,"c");
listArray.remove(0);
System.out.println(listArray);
}
}
/**
* 用数组实现ArrayList
* 泛型不写,固定为String
*/
class ListArray{
//定义String 类型数组用于存储元素
String[] data;
//定义变量表示数组下标/也表示元素个数
int size = 0;
//无参构造 -- 默认,初始容量为10
//ArrayList 默认容量 private static final int DEFAULT_CAPACITY = 10;
public ListArray(){
data = new String[10];
}
//有参构造,指定数组容量
public ListArray(int initCpacity){
data = new String[initCpacity];
}
/**
* 数组扩容
*/
public void grow(){
//首先不考虑用户给定数组长度为负数的情况,因为在0-1 之间没法移位,所以需要分开单独给扩容1个空间
//大于1的情况
//判断数组长度是否为0/1
if (data.length <= 1){
data = Arrays.copyOf(data,data.length+1);
}else {
//因为加号运算符的优先级高于移位运算符,所以data.length>>1 需要加括号
//按照源码,扩容原来空间的50%
/**
* java中有三种移位运算符
* << : 左移运算符,num << 1,相当于num乘以2
* >> : 右移运算符,num >> 1,相当于num除以2
* >>> : 无符号右移,忽略符号位,空位都以0补齐
*/
data = Arrays.copyOf(data,data.length+(data.length>>1));
}
}
/**
* 下标越界
*/
public void isOut(int index){
if(index<0 ||index>=size){
//反馈问题
throw new IllegalArgumentException("Index"+index);
}
}
/**
* 添加元素
* @param str
*/
public void add(String str){
//data[size] = str;
//添加完成一个元素size++,所以也能表示元素个数
//size++;
//判断数组是否需要扩容
if (size >=data.length){
grow();
}
//代码等价于
data[size++] = str;
}
/**
* 插入元素
* @param index 下标
* @param str 插入的元素
*/
public void add(int index,String str){
//判断下标越界问题
if (index<0 || index>size){
//反馈问题
throw new IllegalArgumentException("Index"+index);
}
//判断是否需要扩容
if (size>=data.length){
grow();
}
//插入元素,把选择的元素依次往后进行挪动
//从后往前遍历,位置确定
// for (int i = size-1;i>=index;i--){
// //把前面的元素给后面的进行赋值
// data[i+1] = data[i];
// }
//改进上面的方法
/**
* public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
* 代码解释:
* Object src : 原数组
* int srcPos : 从元数据的起始位置开始
* Object dest : 目标数组
* int destPos : 目标数组的开始起始位置
* int length : 要copy的数组的长度
*/
System.arraycopy(data,index,data,index+1,size-index);
//插入元素
data[index] = str;
//元素个数计数
size++;
}
/**
* 删除元素 --通过下标
* @param index 下标
*/
public void remove(int index){
//下标越界问题,最大下标index = size -1;
isOut(index);
//删除
//把选择的元素内容依次往前挪动
// for (int i =index;i<size-1;i++){
// //后面的给前面的元素赋值
// data[i] = data[i+1];
// }
//简化上面方法
System.arraycopy(data,index+1,data,index,size-index-1);
//元素个数计数
size--;
}
/**
* 根据指定内容删除
*/
public void remove(String str){
//获取返回的第一个下标
int index = indexOf(str);
//判断下标是否为-1
if (index!=-1){
remove(index);
}
}
/**
* 根据指定内容返回第一次出现的下标值
*/
public int indexOf(String str){
//遍历数组元素
for (int i=0;i<size;i++){
//判断集合元素与指定内容是否相等
//data[i]==str 判断2个位null的情况
if (data[i]==str||data[i]!=null&&data[i].equals(str)){
return i;
}
}
//不相等 返回 -1
return -1;
}
/**
* 清空集合
*/
public void clear(){
// clear to let GC do its work
//此步骤先忽略,涉及到垃圾回收
/* for (int i = 0; i < size; i++)
data[i] = null;*/
//元素个数置于0,不会遍历相当于清空集合
size = 0;
}
/**
* 判断集合是否包含给定内容
*/
public boolean contains(String str){
//检查第一次出现的小标值是否为-1
return indexOf(str)!=-1;
}
/**
* 根据下标返回对应的元素值
*/
public String get(int index){
//判断下标越界问题
isOut(index);
//返回数组元素
return data[index];
}
/**
* 判断集合是否为空
*/
public boolean isEmpty(){
//size 代表元素个数
return size == 0;
}
/**
* 替换元素
*/
public void set(int index,String str){
//判断下标越界
isOut(index);
data[index] = str;
}
/**
* 返回元素个数
*/
public int size(){
return size;
}
/**
* 截取子列表
*/
public ListArray subList(int fromIndex,int toIndex){
isOut(fromIndex);
isOut(toIndex);
//保证起始下标小于等于结束下标
if (fromIndex>toIndex){
throw new IllegalArgumentException("FromIndex"+fromIndex+",ToIndex"+toIndex);
}
//截取元素个数
int count = toIndex - fromIndex;
//创建新列表对象,指定初始容量
ListArray list = new ListArray(count);
//把原数组的内容复制到新列表中
System.arraycopy(data,fromIndex,list.data,0,count);
//设置新列表对象的size
list.size = count;
//返回新列表对象
return list;
}
//重写toString 方法,拼接元素内容
public String toString(){
StringBuilder sbr = new StringBuilder("[");
//遍历数组元素,进行拼接操作
for (int i=0;i<size;i++){
sbr.append(data[i]).append(", ");
}
//转成字符串类型
String s = sbr.toString();
//截取子串,把最后的逗号和空格去掉
if (size>0)
s = s.substring(0,s.length()-2);
//拼接中括号
return s+="]";
}
}