List学习

List的实现

  • ArrayList

ArrayList 是一个可改变大小的数组.当更多的元素加入到ArrayList中时,其大小将会动态地增长.内部的元素可以直接通过get与set方法进行访问,因为ArrayList本质上就是一个数组.当需要扩容的时候,ArrayList每次对size增长50%

  • LinkedList

是一个双链表,在添加和删除元素时具有比ArrayList更好的性能.但在get与set方面弱于ArrayList.而 LinkedList 还实现了 Queue 接口,该接口比List提供了更多的方法,包括 offer(),peek(),poll()

  • Vector

Vector 和ArrayList类似,但属于强同步类,Vector每次请求其大小的双倍空间

SynchronizedList和 Vector的区别

Vector是java.util包中的一个类。 SynchronizedList是java.util.Collections中的一个静态内部类。

可以通过Collections.synchronizedList(List list)方法来返回一个线程安全的List。
List<String> list = new ArrayList<String>();
List list2 =  Collections.synchronizedList(list);

两者的区别

  • Vector基本上使用同步方法来实现同步,而SynchronizedList里面实现的方法几乎都是使用同步代码块包上子类List的方法(如果包的是arraylist则包的是arraylist的方法)
  • 两者的扩容机制不一样
  • SynchronizedList没有对遍历的方法进行加锁!所以需要我们手动加锁
  • Collections.synchronizedList() 可以指定加锁的对象!如果没指定那么默认锁的就是list
    ,vector强制锁的是list

通过Array.asList获得的List有何特点

  • asList 得到的只是一个 Arrays 的内部类,一个原来数组的视图 List,因此如果对它进行增删操作会报错
  • 用 ArrayList 的构造器可以将其转变成真正的 ArrayList
  List<String> asList = Arrays.asList("ali","tesion");
  ArrayList arrayList = new ArrayList(asList);
  System.out.println(arrayList);

fail—fast 和 fail—safe的比较

直接粘贴H大的答案:

fail—fast 的特点:


 在用迭代器遍历一个集合对象时,如果遍历过程中对集合对象的内容进行了修改(增加、删除、修改),
 则会抛出ConcurrentModificationException。

          如以下代码,会抛出ConcurrentModificationException:

          for (Student stu : students) {    
              if (stu.getId() == 2)     
                  students.remove(stu);    
          }

          原理:迭代器在遍历时直接访问集合中的内容,并且在遍历过程中使用一个 modCount 变量。
          集合在被遍历期间如果内容发生变化,就会改变modCount的值。每当迭代器使用hashNext()/next()遍历下一个元素之前,
          都会检测modCount变量是否为expectedmodCount值,是的话就返回遍历;否则抛出异常,终止遍历。

      注意:这里异常的抛出条件是检测到 modCount=expectedmodCount 这个条件。
      如果集合发生变化时修改modCount值刚好又设置为了expectedmodCount值,则异常不会抛出。
      因此,不能依赖于这个异常是否抛出而进行并发操作的编程,这个异常只建议用于检测并发修改的bug。

      场景:java.util包下的集合类都是快速失败的,不能在多线程下发生并发修改(迭代过程中被修改)。
      

fail—safe的特点:

      
       采用安全失败机制的集合容器,在遍历时不是直接在集合内容上访问的,而是先复制原有集合内容,在拷贝的集合上进行遍历。

      原理:由于迭代时是对原集合的拷贝进行遍历,所以在遍历过程中对原集合所作的修改并不能被迭代器检测到,
      所以不会触发ConcurrentModificationException。

      缺点:基于拷贝内容的优点是避免了ConcurrentModificationException,但同样地,迭代器并不能访问到修改后的内容
      ,即:迭代器遍历的是开始遍历那一刻拿到的集合拷贝,在遍历期间原集合发生的修改迭代器是不知道的。

      场景:java.util.concurrent包下的容器都是安全失败,可以在多线程下并发使用,并发修改。
      ConcurrentHashMap, CopyOnWriteArrayList, CopyOnWriteArraySet都是符合fail—safe的

terator和ListIterator之间有什么区别

  • Iterator可用于遍历Set、List,ListIterator只可用于List。
  • Iterator只能向后遍历[next(), hasNext()],ListIterator可向前或向后遍历[previous(),
    hasPrevious()]。
  • ListIterator实现了Iterator的接口,并增加了 ①add()方法,可向List添加对象 ②set()方
    法,可修改对象 ③定位索引位置,nextIndex(), previousIndex(

猜你喜欢

转载自blog.csdn.net/whp404/article/details/84575399