List接口常用的实现类有3个:ArrayList、LinkedList和Vector。
我们最常用 ArrayList底层是用数组实现的存储。 特点:查询效率高,增删效率低,线程不安全。
public class Perslist<E> {//原来为Perslist{}
private Object[] elementDate;//核心数组是Object数组,数组名为elementDate
private int size;//定义数组长度
private static final int DEFALT_CAPACITY=10;//定义常量池
public Perslist(){//构造器
elementDate=new Object[DEFALT_CAPACITY];//定义默认数组长度为10
}
public Perslist(int capcity){
if(capcity<0){
throw new RuntimeException("数组容量不能为负数");
}else if(capcity<2){
// Perslist l1=new Perslist(0 or 1);//如果是0或者1 调用add扩容失败 也报出异常,所以要多加一个判断
elementDate = new Object[DEFALT_CAPACITY];
} else {
elementDate = new Object[capcity];//传多少就是多少
}
}
public void add(E obj){//添加一个add方法同时这里也要增加泛型成(E obj)
//什么时候扩容?
if(size==elementDate.length){
//怎样扩容
Object[]newArray=new Object[elementDate.length+(elementDate.length>>1)]; //定义一个更大的数组,相当于原长+原长/2。注意一定要加小括号,因为+优先级大
System.arraycopy(elementDate,0,newArray,0,elementDate.length);
elementDate=newArray;
}
elementDate[size++]=obj;//把传进来
}
@Override
public String toString() {
StringBuilder sb=new StringBuilder();//可变字符序列
sb.append("[");
for(int i=0;i<size;i++){
sb.append(elementDate[i]+",");
}
sb.setCharAt(sb.length()-1,']');
return sb.toString() ;
}
//添加set和get方法
public E get(int index){
check(index);
return (E)elementDate[index];
}
public void set(E e,int index){
//需要判断数组下标是不是越界
check(index);
elementDate[index]=e;
}
//因为很多地方都要用到所以创建一个check方法
public void check(int index){
if(index<0||index>size-1){
throw new RuntimeException("索引不合法"+index);
}
}
public void remove(E e){
for(int i=0;i<size;i++){
if(e.equals(get(i))){
remove(i);
}
}
}
public void remove(int index){
int num=elementDate.length-index-1;
if(num>0){
System.arraycopy(elementDate,index-1,elementDate,index,num);
}
elementDate[size-1]=null;
size--;
}
public static void main(String[] args){
Perslist l1=new Perslist(20);
for(int i=0;i<40;i++){
l1.add("hpu"+i);
}
System.out.println(l1);
System.out.println(l1.get(25));
// System.out.println(l1.get(42));
// 异常索引不合法,我们传进去20,但是add方法中有扩容所以最后数组长度为40,我们想要得到42所以异常
}
}