List

作者: G_uest | 来源:发表于2019-07-26 23:59 被阅读0次
  1. c# List<int> 转 string 以及 s
  2. php redis list
  3. 【Python爬虫】- 第4天列表、元组、集合练习题
  4. Python学习笔记(四)
  5. Android 比较两个集合中的不同元素
  6. JAVA中list的应用+理解
  7. 列表
  8. Python list总结
  9. new为指针
  10. List、 List、 List三者的区别

    继承结构

    • Collection (interface)
      • List (interface)
        • ArrayList (class)
        • LinkedList (class)
        • Vector (class)

    List (interface) 有顺序、可以重复、允许多个null元素

    对比

    使用 说明
    ArrayList 线程不安全
    适合单线程访问时使用
    动态对象数组实现,默认构造方法创建了一个空数组;
    第一次添加元素,容量扩充为10,之后1.5倍扩充,增量为int类型向下取整;
    查找速度快,增删速度慢
    LinkedList 线程不安全
    适合单线程访问时使用
    采用双向链表实现,插入,删除操作,性能高,但是查找速度慢
    Vector
    较少使用
    线程安全
    适合在多线程访问时使用
    动态对象数组实现,默认构造方法创建了一个大小为10的对象数组;
    扩充算法:当增量为0时,扩充为原来的2倍;当增量大于0时,扩充为 原来数组大小+增量;
    不适合进行删除和插入操作;单线程使用时效率较低

    解析

    ArrayList使用动态对象数组实现,每次进行增加或删除操作,都会使操作元素后边的元素位置发生变化(向后或向前移位),所以增删元素相对较慢
    但是因为有索引(数组下标)的存在,所以查找的速度较快,可以使用索引精确的对数据直接操作

    LinkedList使用双向链表实现,对于增删操作可以直接改变节点指向,不需要移动元素,所以增删元素较快
    但是在查找元素时,需要对链表进行遍历,这样查找效率就不如ArrayList速度快

    ArrayList迭代异常

    public static void main(String[] args) {
        // 这里使用 ArrayList 举例,LinkedList结果相同
        List list = new ArrayList();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        // Iterator 迭代器实现迭代,迭代中对集合进行操作会报ConcurrentModificationException
    //      Iterator iterator = list.iterator();
    //      while (iterator.hasNext()) {
    //          Object object = iterator.next();
    //          System.out.println(object);
    //          if (object.equals(3)) {
    //              list.add(10);
    //          }
    //      }
        
        // foreach 实现迭代,迭代中对集合进行操作会报ConcurrentModificationException
    //      for (Object object : list) {
    //          System.out.println(object);
    //          if (object.equals(3)) {
    //              list.add(10);
    //          }
    //      }
    //      System.out.println(list);
        
        // for i 实现迭代
        System.out.println("for i 实现迭代");
        for (int i = 0; i < list.size(); i++) {
            Object obj = list.get(i);
            System.out.print(obj + "  ");
            if (obj.equals(3)) {
                list.add(10);
            }
        }
        System.out.println("\n" + list);
        
        // ListIterator 列表迭代器实现迭代
        System.out.println("ListIterator 列表迭代器实现迭代");
        ListIterator lit = list.listIterator();
        while(lit.hasNext()) {
            Object value = lit.next();
            System.out.print(value + "  ");
            if (value.equals(1)) {
                lit.add("listitertor first add");
            }
        }
        System.out.println("\n" + list);
    }
    

    输出

    for i 实现迭代
    1  2  3  4  10  
    [1, 2, 3, 4, 10]
    ListIterator 列表迭代器实现迭代
    1  2  3  4  10  
    [1, listitertor first add, 2, 3, 4, 10]
    

    异常原因

    在使用迭代器Iterator和foreach对集合迭代过程中,对集合进行增加操作(只有增加操作会报错),会报ConcurrentModificationException并发修改异常
    但是正常for i不会报错,迭代器Iterator报错可以理解,但是foreach为什么会报错呢?
    因为for-each循环隐式地创建了一个迭代器,但它没有向用户公开,因此我们无法修改集合中的项目

    解决方案

    使用List实现类提供的 ListIterator() 方法,ListIterator 是Iterator的子类,使用匿名内部类实现,其中有add方法,可以对集合进行增加操作。

    相关文章