Java 数据结构List之ArrayList

1.泛型

在这里插入图片描述

1.1泛型的使用

class MyArrayList<E> {
    
    
    private E[] elem;
    private int usedSize;

    public MyArrayList() {
    
    
        this.elem = (E[]) new Object[10];
    }

    public void add(E val) {
    
    
        this.elem[usedSize] = val;
        usedSize++;
    }

    public E get(int pos) {
    
    
        return this.elem[pos];
    }
}

public class TestDemo3 {
    
    
    public static void main(String[] args) {
    
    
        MyArrayList<String> myArrayList1 = new MyArrayList();
        System.out.println(myArrayList1);
        MyArrayList<Integer> myArrayList2 = new MyArrayList<>();
        System.out.println(myArrayList2);
        MyArrayList<Boolean> myArrayList3 = new MyArrayList<>();
        System.out.println(myArrayList3);
    }

    public static void main1(String[] args) {
    
    
        MyArrayList<String> myArrayList1 = new MyArrayList();
        myArrayList1.add("ghdfja");
        myArrayList1.add("uyfhyg");
        String ret = myArrayList1.get(1);
        System.out.println(ret);
        MyArrayList<Integer> myArrayList2 = new MyArrayList<>();
        myArrayList2.add(34);
        MyArrayList<Boolean> myArrayList3 = new MyArrayList<>();
        myArrayList3.add(true);
    }
}

2.包装类(Wrapper Class)

在这里插入图片描述
在这里插入图片描述

public static void main(String[] args) {
    
    
        Integer a = 123;//装箱、装包【隐式】
        int b = a;//拆箱、拆包【隐式】
        System.out.println(a + " " + b);

        System.out.println("===============");
        Integer a2 = Integer.valueOf(123);//显示的装包
        Integer a3 = new Integer(123);

        int b2 = a2.intValue();//显示的拆包
        double d = a2.doubleValue();//显示的拆包

        int i = 10;//显示的
    }

面试题:
下面程序的结果分别是啥?

public static void main(String[] args) {
    
    
        Integer a = 127;
        Integer b = 127;
        System.out.println(a == b);
    }

在这里插入图片描述
2.

public static void main(String[] args) {
    
    
        Integer a = 128;
        Integer b = 128;
        System.out.println(a == b);
    }

在这里插入图片描述
在这里插入图片描述

3.List接口,ArrayList类

在这里插入图片描述

  1. ArrayList实现了RandomAccess接口,表明ArrayList支持随机访问
  2. ArrayList实现了Cloneable接口,表明ArrayList是可以clone的
  3. ArrayList实现了Serializable接口,表明ArrayList是支持序列化的
  4. 和Vector不同,ArrayList不是线程安全的,在单线程下可以使用,在多线程中可以选择Vector或者CopyOnWriteArrayList
  5. ArrayList底层是一段连续的空间,并且可以动态扩容,是一个动态类型的顺序表

3.1ArrayList的构造

 public static void main(String[] args) {
    
    
        List<String> list = new ArrayList<>();

        ArrayList<String> list2 = new ArrayList<>();
        list2.add("hello");
        list2.add("bit");
        list2.add("haha");
        System.out.println(list2);


        //使用另外一个list对list3进行初始化
        ArrayList<String> list3 = new ArrayList<>(list2);
        System.out.println(list2);
    }

在这里插入图片描述

3.2ArrayList的打印方式

public static void main(String[] args) {
    
    
        ArrayList<String> list2 = new ArrayList<>();
        list2.add("hello");
        list2.add("bit");
        list2.add("haha");
        System.out.println(list2);
        System.out.println("===================");
        for (int i = 0; i < list2.size(); i++) {
    
    
            System.out.print(list2.get(i) + " ");
        }
        System.out.println();
        System.out.println("===================");
        for (String s : list2) {
    
    
            System.out.print(s + " ");
        }
        System.out.println();
        System.out.println("======迭代器打印=====");
        Iterator<String> it = list2.iterator();
        while (it.hasNext()) {
    
    
            System.out.print(it.next() + " ");
        }
        System.out.println();
        System.out.println("======迭代器List相关打印=====");
        ListIterator<String> it2 = list2.listIterator();
        while (it2.hasNext()) {
    
    
            System.out.print(it2.next() + " ");
        }
    }

在这里插入图片描述
在这里插入图片描述

3.3迭代器(Iterator、ListIterator)的remove方法

***注意:***使用remove()方法,首先需要用next方法迭代集合中的元素,然后才能调用remove方法。

 public static void main(String[] args) {
    
    
        ArrayList<String> list2 = new ArrayList<>();
        list2.add("hello");
        list2.add("bit");
        list2.add("haha");
        System.out.println("======迭代器打印=====");
        Iterator<String> it = list2.iterator();
        /*while (it.hasNext()) {
            String ret = it.next();
            if (ret.equals("hello")) {
                it.remove();//使用remove()方法,首先需要用next方法迭代集合中的元素,然后才能调用remove方法
            } else {
                System.out.print(ret + " ");
            }
        }*/


        System.out.println();
        System.out.println("======迭代器List相关打印=====");
        ListIterator<String> it2 = list2.listIterator();
        while (it2.hasNext()) {
    
    
            String ret = it2.next();
            if (ret.equals("hello")) {
    
    
                it2.remove();
            } else {
    
    
                System.out.print(ret + " ");
            }

        }
    }

在这里插入图片描述

3.4迭代器ListIteratoradd() 方法

public static void main(String[] args) {
    
    
        ArrayList<String> list2 = new ArrayList<>();//单线程
        //CopyOnWriteArrayList<String> list2=new CopyOnWriteArrayList<>();//适用于多线程
        list2.add("hello");
        list2.add("bit");
        list2.add("haha");
        System.out.println("======迭代器打印=====");
        Iterator<String> it = list2.iterator();//没有add()方法
        /*while (it.hasNext()) {
            String ret = it.next();
            if (ret.equals("hello")) {
                it.remove();
            } else {
                System.out.print(ret + " ");
            }
        }*/


        System.out.println();
        System.out.println("======迭代器List相关打印=====");
        ListIterator<String> it2 = list2.listIterator();
        while (it2.hasNext()) {
    
    
            String ret = it2.next();
            if (ret.equals("hello")) {
    
    
                it2.add("张三");
            } else {
    
    
                System.out.print(ret + " ");
            }
        }
        System.out.println();
        System.out.println(list2);
    }

Iterator没有add()方法。

在这里插入图片描述

3.5ArrayList和 CopyOnWriteArrayList

在这里插入图片描述

 public static void main(String[] args) {
    
    
        //ArrayList<String> list2 = new ArrayList<>();//单线程
        CopyOnWriteArrayList<String> list2=new CopyOnWriteArrayList<>();//适用于多线程
        list2.add("hello");
        list2.add("bit");
        list2.add("haha");
        System.out.println("======迭代器List相关打印=====");
        ListIterator<String> it2 = list2.listIterator();
        while (it2.hasNext()) {
    
    
            String ret = it2.next();
            if (ret.equals("bit")) {
    
    
                list2.add("张三");
            } else {
    
    
                System.out.print(ret + " ");
            }
        }
        System.out.println();
        System.out.println(list2);
    }

在这里插入图片描述

在这里插入图片描述

3.6ArrayList的常见操作

在这里插入图片描述

public static void main(String[] args) {
    
    
        ArrayList<String> list2 = new ArrayList<>();
        list2.add("a");
        list2.add("b");
        list2.add("c");
        System.out.println(list2);
        list2.add(0,"gaobo");
        System.out.println(list2);

        ArrayList<String> list3 = new ArrayList<>();
        list3.add("我是测试1");
        list3.add("我是测试2");
        list3.add("我是测试3");
        list2.addAll(list3);
        System.out.println(list2);
        System.out.println(list3);;
    }

在这里插入图片描述

public static void main(String[] args) {
    
    
        ArrayList<String> list2 = new ArrayList<>();
        list2.add("a");
        list2.add("b");
        list2.add("c");
        System.out.println(list2);
        list2.set(0,"gaobo");
        System.out.println(list2);
        list2.remove(2);
        System.out.println(list2);
    }

在这里插入图片描述

public static void main(String[] args) {
    
    
        ArrayList<String> list2 = new ArrayList<>();
        list2.add("a");
        list2.add("c");
        list2.add("g");
        list2.add("a");
        list2.add("o");
        List<String> sub = list2.subList(1, 3);
        System.out.println(sub);
        System.out.println(list2);
        System.out.println("+++++++++++++++++++");
        sub.set(0, "ppp");
        System.out.println(sub);
        System.out.println(list2);
    }

在这里插入图片描述
从代码和运行结果可以看出,subList()是左闭右开,并且并不是真正的截取出来了。

在这里插入图片描述

3.7ArrayList的容量问题

在这里插入图片描述
在这里插入图片描述

4.ArrayList的模拟实现

import java.util.Arrays;

/**
 * Created with IntelliJ IDEA
 * Description:
 * User: 23006
 * Date: 2021-11-28
 * Time: 15:46
 * main: psvm
 * 打印: sout
 */
public class MyArrayList<E> {
    
    
    private Object[] elementData;//数组
    private int usedSize;//代表有效数据个数

    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {
    
    };

    public MyArrayList() {
    
    
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }

    public MyArrayList(int capacity) {
    
    
        //对参数进行判断
        if (capacity > 0) {
    
    
            this.elementData = new Object[capacity];
        } else if (capacity == 0) {
    
    
            this.elementData = new Object[0];
        } else {
    
    
            throw new IllegalArgumentException("初始化容量不能为负数!");
        }
    }

    /**
     * 添加元素,存放在数组最后位置
     *
     * @param e 数据
     * @Description:添加元素
     * @return: boolean
     */
    public boolean add(E e) {
    
    
        //确定真正的容量  ,预测-》扩容
        ensureCapacityInternal(usedSize + 1);
        elementData[usedSize] = e;
        usedSize++;
        return true;
    }

    private void ensureCapacityInternal(int minCapacity) {
    
    
        //1.计算出需要的容量
        int capacity = calculateCapacity(elementData, minCapacity);
        //2.拿着容量  去看   满了就扩容  空的也是扩容
        ensureExplicitCapacity(capacity);
    }

    private void ensureExplicitCapacity(int minCapacity) {
    
    
        //进不去if语句,说明数组还没放满
        if (minCapacity - elementData.length > 0)
            //扩容了
            grow(minCapacity);
    }

    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

    private void grow(int minCapacity) {
    
    
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);//1.5倍扩容
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        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);
    }

    private static int hugeCapacity(int minCapacity) {
    
    
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError();
        return (minCapacity > MAX_ARRAY_SIZE) ?
                Integer.MAX_VALUE :
                MAX_ARRAY_SIZE;
    }

    private static int calculateCapacity(Object[] elementData, int minCapacity) {
    
    
        //1.判断之前elementData数组是否分配过大小
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
    
    
            return Math.max(10, minCapacity);
        }
        //2.分配过,就返回+1后的值
        return minCapacity;
    }

    /**
     * @param index
     * @param e
     * @Description:在index位置添加元素e
     */
    public void add(int index, E e) {
    
    
        //1.检查下标合法性
        rangeCheckForAdd(index);
        //2.确定真正的容量
        ensureCapacityInternal(usedSize + 1);
        //3.挪数据
        copy(index, e);
        usedSize++;
    }

    private void copy(int index, E e) {
    
    
        for (int i = usedSize - 1; i >= index; i--) {
    
    
            elementData[i + 1] = elementData[i];
        }
        elementData[index] = e;
    }

    private void rangeCheckForAdd(int index) {
    
    
        if (index < 0 || index > size()) {
    
    
            throw new IndexOutOfBoundsException("index不合法,请重新輸入!");
        }
    }

    /**
     * @param
     * @Description:獲取順序表大小
     * @return: int
     */
    private int size() {
    
    
        return this.usedSize;
    }
}

测试:

/**
 * Created with IntelliJ IDEA
 * Description:
 * User: 23006
 * Date: 2021-11-28
 * Time: 16:34
 * main: psvm
 * 打印: sout
 */
public class TestMyArrayList {
    
    
    public static void main(String[] args) {
    
    
        MyArrayList<String> list = new MyArrayList<>();
        list.add("ab");
        list.add("abc");
        list.add("abcd");
        list.add("abcde");
        list.add(4,"张三");
        System.out.println("dgsfdh");
    }
}

调试一下:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_44721738/article/details/121549208