ArrayList和ArrayList的模拟实现

ArrayList是集合中的一种重要数据结构,是线性表中的一种,它的底层是一个动态变化的数组。

1.ArrayList的构造:

无参构造——ArrayList()

利用其他Collection构建ArrayList——ArrayList(Collection<?extends E>c)(Collection里面的数据类型是E本身或E的子类)

指定顺序表初始容量——ArrayList(int initialCapacity)

public static void main(String[] args){
    //构造一个空列表
    List<Integer> list1 = new ArrayList<>();

    //构造一个具有10个容量的列表
    List<Integer> list2 = new ArrayList<>(10);

    //也可以利用一个集合构建一个顺序表
    ArrayList<Integer> list3 = new ArrayList<>(list2);

    ArrayList<String> list3 = new ArrayList<>(list2);//这里会报错,因为list2的类型是Integer,不是String及其子类
}

 2.ArrayList常见操作

boolean add(E e)                              尾插e
void add(int index,E element)                 将e插入到index位置,index位置必须合法,否者会报IndexOutOfBoundsException异常
boolean addAll(Collection<? extends E>c)      尾插c中的元素
E remove(int index)                           删除index位置元素
E remove(Collection<?> c)                     在集合E中删除包含集合c中的所有元素
boolean remove(Object o)                      删除遇到的第一个o
E get(int index)                              获取下标index位置元素
E set(int index,E element)                    将下标index位置元素设置为element
void clear()                                  清空
boolean contains(Object o)                    判断o是否在线性表中
int indexOf(Object o)                         返回第一个o所在下标
int lastindexOf(Object o)                     返回最后一个o的下标
List<E> subList(int formIndex,int toIndex)    截取部分list

注意:在删除遇到的第一个o时会遇到系统自动将数字定义为下标的情况,这里需要使用Integer.valueOf()

3.ArrayList的遍历

ArrayList可以使用三种方式遍历:for循环+下标、foreach、使用迭代器(只要实现了iterable接口的集合都可以使用)

public class TestDemo {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();
        ArrayList<Integer> list1 = new ArrayList<>();
        list.add(1);
        list.add(13);
        list.add(2);
        list.add(100);
        list.add(610);
        list.add(1);
        list.add(13);
        list.add(2);
        for (int i = 0; i < list.size(); i++) {
           System.out.print(list.get(i)+" ");
        }
    }
}
for (Integer object:
      list) {
     System.out.print(object+" ");
}

        ListIterator<Integer> iterator = list.listIterator();
        while(iterator.hasNext()){
            System.out.print(iterator.next()+" ");
        }

这里的iterator.hasNext()的功能是判断iterator是否有下一个元素,有就进入循环
System.out.print(iterator.next()+" ")表示打印iterator的下一个元素,并向下走一步

4.ArrayList的模拟实现

ArrayList底层是一个动态变化的数组,为了体现动态变化,就必须有相应的操作,记录这个操作最重要的就是记录数组当中的元素个数。所以ArrayList最重要的就两点:1.数组;2:数组中的元素个数usedsize

public class MyArrayList {
    public int[] elem;
    public int usedsize;
    private static final int initCapcity = 4;
    public MyArrayList(){
        this.elem = new int[initCapcity];
    }
}

下面实现ArrayList里面的一部分功能

1.添加元素(尾插)

    public boolean justfull(){
        return usedsize== elem.length;
    }   

    public void add(int data){
        if(justfull()){//如果满了就扩容
            this.elem = Arrays.copyOf(this.elem,2*elem.length);
        }
        //新增元素
        elem[usedsize++] = data;
    }

2.打印顺序表

    public void display(){
        for (int i = 0; i < usedsize; i++) {
            System.out.print(elem[i]+" ");
        }
        System.out.println();
    }

主函数里面实现一下

public class TestDemo {
    public static void main(String[] args) {
        MyArrayList arrayList = new MyArrayList();
        arrayList.add(1);
        arrayList.add(2);
        arrayList.add(3);
        arrayList.add(41);
        arrayList.add(5);
        arrayList.add(7);
        arrayList.add(41);
        arrayList.display();
    }
}

3.在指定位置添加新元素 

思路:

1.首先判断指定位置的合法性(0<=pos<=usedsize合法)

2.插入数据

    public boolean justPos(int pos){
        return pos<0||pos>usedsize?true:false;
    }
    public void add(int pos, int data) {
        if (justfull()) {//判断数组是否满
            this.elem = Arrays.copyOf(this.elem, 2 * elem.length);
        }
        if (justPos(pos)) {
            throw new MyArrayListindexOutofException("指定的位置不合法");
        } else {
            for (int i = usedsize; i > pos; i--) {
                elem[i] = elem[i - 1];
            }
            elem[pos] = data;
            usedsize++;
        }
    }

 主函数里面实现一下

public class TestDemo {
    public static void main(String[] args) {
        MyArrayList arrayList = new MyArrayList();
        arrayList.add(1);
        arrayList.add(2);
        arrayList.add(3);
        arrayList.add(41);
        arrayList.add(5);
        arrayList.add(7);
        arrayList.add(41);
        arrayList.display();

        arrayList.add(7,21);
        arrayList.display();
    }
}

4.判断顺序表中是否包含某个元素 

    public boolean contains(int data){
        for (int i = 0; i < usedsize; i++) {
            if(elem[i] == data){//这里如果是引用类型,要重写equals方法
                return true;
            }
        }
        return false;
    }

 主函数里面实现一下

public class TestDemo {
    public static void main(String[] args) {
        MyArrayList arrayList = new MyArrayList();
        arrayList.add(1);
        arrayList.add(2);
        arrayList.add(3);
        arrayList.add(41);
        arrayList.add(5);
        arrayList.add(7);
        arrayList.add(41);

        if(arrayList.contains(21)){
            System.out.println("存在");
        }else{
            System.out.println("不存在");
        }
    }
}

 5.获取pos位置的元素

    public int get(int pos){
        if(pos<0||pos>=usedsize){
            throw new MyArrayListindexOutofException("指定的位置不合法");
        }
        int i = 0;
        for (; i < usedsize; i++) {
            if(i==pos){
                break;
            }
        }
        return elem[i];
    }
public class MyArrayListindexOutofException extends RuntimeException{
    public MyArrayListindexOutofException() {
    }
    public MyArrayListindexOutofException(String message){
        super(message);
    }
}

主函数里面实现一下

public class TestDemo {
    public static void main(String[] args) {
        MyArrayList arrayList = new MyArrayList();
        arrayList.add(1);
        arrayList.add(2);
        arrayList.add(3);
        arrayList.add(41);
        arrayList.add(5);
        arrayList.add(7);
        arrayList.add(41);
        System.out.println(arrayList.get(5));
    }
}

 6.将pos位置的元素设为value

    public void set(int pos,int value){
        if(pos<0||pos>=usedsize){
            throw new MyArrayListindexOutofException("指定的位置不合法");
        }
        for (int i = 0; i < usedsize; i++) {
            if(i==pos){
                elem[i] = value;
                break;
            }
        }
    }

主函数里面实现一下

public class TestDemo {
    public static void main(String[] args) {
        MyArrayList arrayList = new MyArrayList();
        arrayList.add(1);
        arrayList.add(2);
        arrayList.add(3);
        arrayList.add(41);
        arrayList.add(5);
        arrayList.add(7);
        arrayList.add(41);
        arrayList.display();

        arrayList.set(4,99);
        arrayList.display();
    }
}

7.删除第一次出现的关键字key 

    public void remove(int toRemove){
        int i = 0;
        for (; i < usedsize; i++) {
            if(elem[i] == toRemove){
                for (int j = i; j < usedsize; j++) {
                    elem[j] = elem[j+1];
                }
                usedsize--;
                break;
            }
        }
        if(i==usedsize){
            System.out.println("没有你要删除的数据");
        }
    }

 主函数里面实现一下

public class TestDemo {
    public static void main(String[] args) {
        MyArrayList arrayList = new MyArrayList();
        arrayList.add(1);
        arrayList.add(2);
        arrayList.add(3);
        arrayList.add(41);
        arrayList.add(5);
        arrayList.add(7);
        arrayList.add(41);
        arrayList.display();

        arrayList.remove(41);
        arrayList.display();
    }
}

 8.计算顺序表的长度和清空顺序表


    public int size(){
        return usedsize;
    }

    public void clear(){
//        for (int i = 0;i<usedsize;i++){//如果是引用类型,要一个一个置为空
//            elem[i] = null;
//        }
        usedsize =0;
    }

5.ArrayList底层原码分析

当我们创建ArrayList一个不带参数的构造方法时,我们发现它底层数组的默认初始容量为0

 

只有当第一次添加数据的时候,数组的容量才变为10

猜你喜欢

转载自blog.csdn.net/yahid/article/details/125184002
今日推荐