Java集合框架详解--List详解(三)

一、List接口

List是一个接口,定义了一组元素是有序的、可重复的集合。通过索引来访问List中的元素。

List 继承自 Collection,较之 Collection,List 还添加了以下操作方法

  • 位置相关:List 的元素是有序的,因此有get(index)、set(index,object)、add(index,object)、remove(index) 方法。
  • 搜索:indexOf(),lastIndexOf();
  • 迭代:使用 Iterator 的功能板迭代器
  • 范围性操作:使用 subList 方法对 list 进行任意范围操作。

实现List接口的集合主要有:ArrayList、LinkedList、Vector、Stack

二、List的实现类

1.ArrayList

ArrayList的实现原理

(1)如果在初始化ArrayList的时候没有指定初始化长度,默认长度为10。如果我们明确所插入的元素的多少,最好指定一个初始容量值,避免过多的进行扩容操作而浪费时间,影响效率。

/**
 * Constructs an empty list with an initial capacity of ten.
 */
 public ArrayList() {
     this(10);
 }

(2)每次向集合中添加元素时,要做容量检查,当快要溢出时,进行扩容操作,ArrayList扩容ensureCapacity的方案为:

原始容量*3/2+1

/**
 * Increases the capacity of this <tt>ArrayList</tt> instance, if
 * necessary, to ensure that it can hold at least the number of elements
 * specified by the minimum capacity argument.
 *
 * @param   minCapacity   the desired minimum capacity
 */
public void ensureCapacity(int minCapacity) {
modCount++;
int oldCapacity = elementData.length;
if (minCapacity > oldCapacity) {
    Object oldData[] = elementData;
    int newCapacity = (oldCapacity * 3)/2 + 1;
        if (newCapacity < minCapacity)
    newCapacity = minCapacity;
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);
}
}

(3)ArrayList是线程不安全的,在多线程的情况下不要使用。

如果一定要在多线程使用List,可以使用Vector,因为Vector和ArrayList基本一致,但是Vector是线程安全的,还有就是两者的扩容方案不一致,ArrayList是通过(原始容量*3/2+1)实现的,而Vector是允许设置默认增长长度的,Vector的默认扩容方式为原来的两倍。

(4)ArrayList实现遍历的几种方法

import java.util.*;
 
public class Test{
 public static void main(String[] args) {
     List<String> list=new ArrayList<String>();
     list.add("Hello");
     list.add("World");
     list.add("HAHAHAHA");
     //第一种遍历方法使用foreach遍历List
     for (String str : list) {            //也可以改写for(int i=0;i<list.size();i++)这种形式
        System.out.println(str);
     }
 
     //第二种遍历,把链表变为数组相关的内容进行遍历
     String[] strArray=new String[list.size()];
     list.toArray(strArray);
     for(int i=0;i<strArray.length;i++) //这里也可以改写为  foreach(String str:strArray)这种形式
     {
        System.out.println(strArray[i]);
     }
     
    //第三种遍历 使用迭代器进行相关遍历
     
     Iterator<String> ite=list.iterator();
     while(ite.hasNext())//判断下一个元素之后有值
     {
         System.out.println(ite.next());
     }
 }
}

ArrayList如下特点:

  • 容量不固定,可以动态扩容
  • 有序(基于数组实现,查找快,增删慢)
  • 元素可以为null
  • 效率高
  • 占用空间少,相比LinkedList,不用额外空间维护表结构

2.LinkedList

LinkedList的实现原理

3.ArrayList和LinkedList的区别

(1)当随机访问List时(get和set操作),ArrayList比LinkedList的效率更高,因为LinkedList是链表的数据结构,需要移动指针。

(2)当对数据进行增删操作是,LinkedList比ArrayList的效率更高,因为ArrayList的实现基于数组,进行增删操作需要移动元素。

(3)ArrayList基于数组数据结构,LinkedList基于链表数据结构。

4.Vector(已过时)

与ArrayList大同小异,主要是Vector是线程安全的。如果考虑线程安全,可以使用Vector。

与ArrayList的区别:

(1)Vector是线程安全的,ArrayList则不是。

(2)Vector默认扩容是原来的两倍,ArrayList是原来的1.5倍(原来容量*3/2+1)。

(3)Vector多了一种迭代器Enumeration。

5.Stack

Stack继承Vector,也是一个线程安全的集合。

Stack也是基于数组实现的。

Stack实现的是栈结构集合。

猜你喜欢

转载自blog.csdn.net/weixin_38178449/article/details/82943818