zoukankan      html  css  js  c++  java
  • 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();
            }
        }
    

      

      

  • 相关阅读:
    《梦断代码》读书计划
    四则运算3
    《梦断代码》读后感Ⅱ
    第二次结对开发
    首次结对开发
    四则运算2的测试
    四则运算2的任务完成时间表
    四则运算2
    《梦断代码》观后感1
    四则运算2的心路历程
  • 原文地址:https://www.cnblogs.com/knsbyoo/p/14070967.html
Copyright © 2011-2022 走看看