Java基础-ArrayList

一. 类说明

 ArrayList是List接口的可调整大小的数组的实现。实现了所有可选的list操作,并允许元素为null。除了实现List接口之外,此类还提供了一些方法来操作内部用于存储列表的数组大小。这个类大致等同于Vector,只是它不同步。

    这些操作siz, isEmpty, get, set, iterator和listIterator运行在“恒定”时间。这个add操作运行在“amortized constant time”(非恒定时间),因此,新增一个元素需要O(n)时间。所有的操作都是在线性时间运行的(粗略地说)。与LinkList相比,常量因子较低。

   每一个ArrayList实例都有容量。容量事一个数组用来存储元素的大小在列表中。他总是至少和列表一样大小。当元素添加到ArrayList,他的容量会自动增长。除了新增元素具有一个固定的摊余时间成本这一个事实外,增长策略的细节没有被指定。

   应用程序可以使用增加ArrayList实例的容量,在对他进行添加大量元素之前,这样可以减少增量重新分配的数量。

   请注意,此实现不是同步的。如果多个线程同时访问一个ArrayList实例,并且至少有一个线程在结构上修改了该列表,那么他必须在外部同步。(结构修改是指添加或者删除一个多个元素,或者显示调整后备数组大小的任何操作)这通常是通过在一些自然封装列表的对象上进行同步来实现的。如果不存在这样的对象,则应该使用该方法对list进行包装,如下:

 

List list = Collections.synchronizedList(new ArrayList(...));

 

 

   快速失败(fail-fast)

 

  如果在迭代器创建后的任何时候去列表进行结构上的修改(除了通过迭代器使用自己的remove()或者add()外),该类的返回的迭代器和方法将快速失败,迭代器将抛出一个ConcurrentModificationException。因此,在并发修改的情况下,迭代器会迅速而彻底地失败,而不是在将来某个不确定的时间冒着任意不确定的风险。

   请注意,迭代器的fail-fast的行为得不到保证。一般来说,在存在不同步的并发修改时,不可能做出任何硬保证,会尽最大努力抛出ConcurrentModificationException。因此编写一个依赖于这个异常来保证正确性的程序是错误的,这个只能用来检测bug。

二. 常见的方法

   public static void main(String[] args){
        ArrayList<Integer> arrayList = new ArrayList<>();
        initList(arrayList);
        System.out.println("数组:" + arrayList.toString());
        System.out.println("arrayList.get(0):" + arrayList.get(0));
        System.out.println("size:" + arrayList.size());//元素的个数
        System.out.println("isEmpty:" + arrayList.isEmpty());
        System.out.println("是否包含9:" + arrayList.contains(9));
        System.out.println("匹配查找的第一个元素值是9的索引:" + arrayList.indexOf(9));
        System.out.println("匹配查找的最后个元素值是9的索引:" + arrayList.lastIndexOf(9));
        System.out.println(Arrays.toString(arrayList.toArray(new Integer[0])));//将list转换为数组
        arrayList.ensureCapacity(12);
        arrayList.add(11);//modeCount+1,检测是否需要扩容
        System.out.println("数组新增元素:" + arrayList.toString());
        arrayList.remove(2);
        System.out.println("数组删除元素:" + arrayList.toString());
        arrayList.clear();
        System.out.println("数组清空元素:" + arrayList.toString());
        initList(arrayList);//size和capacity的概念不一样,size是元素的数量,capacity是底层数组的大小,
        ArrayList<Integer> arrayList2 = new ArrayList<>();
        arrayList2.add(2);arrayList.add(111);
        arrayList.addAll(arrayList2);
        System.out.println("数组A添加数组B:" + arrayList.toString());
        arrayList.removeAll(arrayList2);
        System.out.println("数组A移除数组B的元素:" + arrayList.toString());
        arrayList.add(1);arrayList.add(2);arrayList.add(5);
        arrayList.retainAll(arrayList2);//交集
        System.out.println("数组A与数组B的交集:" + arrayList.toString());
        initList(arrayList);
        Iterator<Integer> iterator = arrayList.iterator();
        iterator.forEachRemaining(x -> System.out.println("迭代剩余的元素forEachRemaining:" + x));
        List<Integer> arrayList3 = arrayList.subList(0,2);//截取
        System.out.println("arrayList截取:" + arrayList3.toString());
        arrayList3.sort(Integer::compareTo);
        System.out.println("排序后:" + arrayList3.toString());
    }

  输出

数组:[1, 2, 10, 9, 8, 9]
arrayList.get(0):1
size:6
isEmpty:false
是否包含9:true
匹配查找的第一个元素值是9的索引:3
匹配查找的最后个元素值是9的索引:5
[1, 2, 10, 9, 8, 9]
数组新增元素:[1, 2, 10, 9, 8, 9, 11]
数组删除元素:[1, 2, 9, 8, 9, 11]
数组清空元素:[]
数组A添加数组B:[1, 2, 10, 9, 8, 9, 111, 2]
数组A移除数组B的元素:[1, 10, 9, 8, 9, 111]
数组A与数组B的交集:[2]
迭代剩余的元素forEachRemaining:2
迭代剩余的元素forEachRemaining:1
迭代剩余的元素forEachRemaining:2
迭代剩余的元素forEachRemaining:10
迭代剩余的元素forEachRemaining:9
迭代剩余的元素forEachRemaining:8
迭代剩余的元素forEachRemaining:9
arrayList截取:[2, 1]
排序后:[1, 2]

Process finished with exit code 0

  

 

 三. 几种遍历的方法一览

   public static void forDemo(ArrayList<Integer> list){
        for (int i = 0; i < list.size(); i++){//普通for循环
            //数组是在存储在连续的内存空间的有序的序列
            System.out.println(i);
        }
    }

    public static void enhanceForDemo(ArrayList<Integer> list){
        for(Integer i : list){//增强for循环,内部使用迭代器
            System.out.println(i);
        }
    }

    public static void foreach(ArrayList<Integer> list){
        //内部也是使用普通for循环的
        list.forEach(integer -> System.out.println(integer));
    }

  增强for循环使用迭代器,可看编译后文件

    public static void enhanceForDemo(ArrayList<Integer> list) {
        Iterator var1 = list.iterator();

        while(var1.hasNext()) {
            Integer i = (Integer)var1.next();
            System.out.println(i);
        }

    }

  foreach内部实现代码

    @Override
    public void forEach(Consumer<? super E> action) {
        Objects.requireNonNull(action);
        final int expectedModCount = modCount;
        @SuppressWarnings("unchecked")
        final E[] elementData = (E[]) this.elementData;
        final int size = this.size;
        for (int i=0; modCount == expectedModCount && i < size; i++) {
            action.accept(elementData[i]);
        }
        if (modCount != expectedModCount) {
            throw new ConcurrentModificationException();
        }
    }

  

 

  

posted @ 2020-12-01 21:46  knbsyoo  阅读(110)  评论(0编辑  收藏  举报