目录
List接口特有的常用方法
ArrayList
集合ArrayList 的构造方法
将 ArrayList 转换为线程安全的方法
LinkedList
LinkedList构造方法
ArrayList 和 Array 的区别
ArrayList 和 LinkedList 的区别
Vector
List接口特有的常用方法
ArrayListList存储元素特点:有序可重复,且List集合中元素有下标(从0开始)
(1)void add(int index,E element) 在列表的指定位置插入指定元素
index索引即是该List中的下标,element为你插入的元素,如下图:
import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class List方法 { public static void main(String[] args) { List arr = new ArrayList(); arr.add("a"); arr.add("b"); arr.add("c"); //调用List中特有的add方法 arr.add(2,"java"); Iterator it = arr.iterator(); while (it.hasNext()){ Object ob = it.next(); System.out.println(ob); } } }
结果图:
(2)E set(int index,E element) 用指定元素替换列表中指定位置的元素
import java.util.ArrayList; import java.util.List; public class List方法 { public static void main(String[] args) { List arr = new ArrayList(); arr.add("a"); arr.add("b"); arr.add("c"); arr.add("a"); System.out.println("初始的元素序列为:"); for( int i = 0 ; i < arr.size() ; i++){ Object obj = arr.get(i); System.out.println(obj); } //替换指定位置下标的元素 arr.set(2,"java"); System.out.println("替换后后元素序列为:"); for( int i = 0 ; i < arr.size() ; i++){ Object obj = arr.get(i); System.out.println(obj); } } }
结果图:
(3)E get(int index) 返回列表中指定位置的元素
import java.util.ArrayList; import java.util.List; public class List方法 { public static void main(String[] args) { List arr = new ArrayList(); arr.add("a"); arr.add("b"); arr.add("c"); //调用List中特有的add方法 arr.add(2,"java"); for( int i =0 ; i< arr.size(); i++){ //调用get方法 Object obj = arr.get(i); System.out.println(obj); } } }
结果图:
(4) int indexOf(Object o) 返回列表中首次出现指定元素的索引,如果列表不包含此元素,则返回-1。
import java.util.ArrayList; import java.util.List; public class List方法 { public static void main(String[] args) { List arr = new ArrayList(); arr.add("a"); arr.add("b"); arr.add("c"); arr.add("a"); //获取 “a” 第一次出现时的索引 System.out.println(arr.indexOf("a")); //获取 “a” 最后一次出现时的索引 System.out.println(arr.lastIndexOf("a")); //如果没有指定元素时 System.out.println(arr.indexOf("java")); } }
结果图:
(5)E remove(int index) 移除列表中指定位置的元素
import java.util.ArrayList; import java.util.List; public class List方法 { public static void main(String[] args) { List arr = new ArrayList(); arr.add("a"); arr.add("b"); arr.add("c"); arr.add("a"); System.out.println("初始的元素序列为:"); for( int i = 0 ; i < arr.size() ; i++){ Object obj = arr.get(i); System.out.println(obj); } //删除指定位置下标的元素 arr.remove(3); System.out.println("删除后元素序列为:"); for( int i = 0 ; i < arr.size() ; i++){ Object obj = arr.get(i); System.out.println(obj); } } }
结果图:
集合ArrayList 的构造方法(1)ArrayList 初始化容量为0,可以指定容量,未添加元素时为一个空数组,添加元素后默认容量由0 变为10
/** * Default initial capacity. */ private static final int DEFAULT_CAPACITY = 10;
(2)集合底层是一个Object类型的数组
/** * Shared empty array instance used for empty instances. */ private static final Object[] EMPTY_ELEMENTDATA = {};
(3)会自动扩容1.5倍
先将旧容量右移1位,再加上旧容量就得到了新容量,正数右移1位相当于除以2,在该基础上加旧容量,则等价于新容量 = 旧容量 * 1.5,所以才有ArrayList每次扩容为旧容量的1.5倍的说法,最后调用Arrays.copyOf()方法进行拷贝,并将elementData指向新数组,而旧数组因为没有引用指向它,很快就会被垃圾收集器回收掉
/** * Increases the capacity to ensure that it can hold at least the * number of elements specified by the minimum capacity argument. * * @param minCapacity the desired minimum capacity * @throws OutOfMemoryError if minCapacity is less than zero */ private Object[] grow(int minCapacity) { int oldCapacity = elementData.length; if (oldCapacity > 0 || elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { int newCapacity = ArraysSupport.newLength(oldCapacity, minCapacity - oldCapacity, /* minimum growth */ oldCapacity >> 1 /* preferred growth */); return elementData = Arrays.copyOf(elementData, newCapacity); } else { return elementData = new Object[Math.max(DEFAULT_CAPACITY, minCapacity)]; } }
ArrayList() 构造一个初始容量为十的空列表 ArrayList(int initialCapacity) 构造具有指定初始容量的空列表 ArrayList(Collection extends E> c) 构造一个包含指定集合的元素的列表,按照它们由集合的迭代器返回的顺序
将 ArrayList 转换为线程安全的方法(1)无参构造
/** * The array buffer into which the elements of the ArrayList are stored. * The capacity of the ArrayList is the length of this array buffer. Any * empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA * will be expanded to DEFAULT_CAPACITY when the first element is added. * ArrayList的缓冲数组,里面存储的是ArrayList数据。ArrayList的容量长度就是这个数组的长度,任何空的使用elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA初始化的ArrayList在添加第一个元素时都会被扩容为DEFAULT_CAPACITY (10) */ transient Object[] elementData; /** * Shared empty array instance used for default sized empty instances. We * distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when * first element is added. * 用于默认大小的空的共享空数组实例。我们将此与EMPTY_ELEMENTDATA区分开来,以便在添加第一个元素时知道需要扩张多少。 */ private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; /** * Constructs an empty list with an initial capacity of ten. * 构造一个初始容量为10的空list。 */ public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; }
(2)指定容量
ArrayList(int initialCapacity)
入参是ArrayList初始化容量,如果容量小于0就抛错,否则实例化一个Object对象数组赋值给全局变量elementData
public ArrayList(int initialCapacity) { // 容量大于0,按照指定的容量初始化数组 if (initialCapacity > 0) { // 创建一个数组,且指定长度为initialCapacity this.elementData = new Object[initialCapacity]; // 如果initialCapacity容量为0,把EMPTY_ELEMENTDATA的地址赋值给elementData } else if (initialCapacity == 0) { this.elementData = EMPTY_ELEMENTDATA; // 容量小于0,抛非法异常 } else { throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); } }
(3)指定集合
ArrayList(Collection extends E> c)
传入Collection集合的对象,将传入的集合对象转为数组,然后给size赋值,判断如果传入的对象数组不是Object[],则转为Object[]
public ArrayList(Collection extends E> c) { // 将给定的集合对象转成数组,且将数组的地址赋值给elementData elementData = c.toArray(); // 将elementData的长度赋值给集合长度size,且判断是否不等于 0 if ((size = elementData.length) != 0) { // 判断elementData 和 Object[] 是否为不一样的类型 // c.toArray()数组不是object数组进行转换成Object[] // 每个集合的toarray()的实现方法不一样,所以需要判断一下,如果不是Object[].class类型,那么就需要使用ArrayList中的方法去改造一下。 // elementData.getClass()到底是什么类型的? if (elementData.getClass() != Object[].class) // 转换Object[] // 如果不一样,使用Arrays的copyOf方法进行元素的拷贝 elementData = Arrays.copyOf(elementData, size, Object[].class); } else { // 给定的数组的长度为0,用空数组代替 this.elementData = EMPTY_ELEMENTDATA; } }
LinkedListCollections.synchronizedList()
import java.util.Collections; import java.util.List; import java.util.ArrayList; public class ArrayListTest { public static void main(String[] args) { //默认容量为10,此时线程是不安全的 List list1 = new ArrayList(); //变成线程安全的方法 Collections.synchronizedList(list1); list1.add(1); list1.add(1); list1.add(1); list1.add(1); } }
LinkedList构造方法(1)LinkedList 的底层是一个双向链表(包含两个指针的,pre指向前一个节点,next指向后一个节点,但是第一个节点head的pre指向null,最后一个节点的tail指向null)
注意:JDK1.6时为双向循环链表(第一个节点的pre指向最后一个节点,最后一个节点的next指向第一个节点,也形成一个“环”)而在JDK1.7以及往后版本,底层实现为双向链表
JDK1.8源码
public class LinkedList
extends AbstractSequentialList implements List , Deque , Cloneable, java.io.Serializable { //长度 transient int size = 0; //指向头结点 transient Node first; //指向尾结点 transient Node last; } (2)元素在空间存储上的内存不连续,随机增删元素时,不会有大量元素移动,所以增删效率高,查找效率低
ArrayList 和 Array 的区别(1)无参构造(public LinkedList())
/** * Constructs an empty list. */ public LinkedList() { }
(2)有参构造(public LinkedList(Collection extends E> c))
/** * Constructs a list containing the elements of the specified * collection, in the order they are returned by the collection's * iterator. * * @param c the collection whose elements are to be placed into this list * @throws NullPointerException if the specified collection is null */ public LinkedList(Collection extends E> c) { this(); addAll(c); }
Array 可以容纳基本类型和对象,而 ArrayList 只能容纳对象。 Array 是指定大小的,而 ArrayList 大小是固定ArrayList 和 LinkedList 的区别
(1)ArrrayList 底层的数据结构是数组,支持随机访问,而 LinkedList 的底层数据结构是双向循环链表,不支持随机访问 (2)使用下标访问一个元素, ArrayList 的时间复杂 度是 O(1) ,而 LinkedList 是 O(n)Vector
(1)Vector 底层也是一个数组,初始化容量为10
(2)扩容后,容量为原容量的两倍
(3)Vector 中的所有方法都是线程同步的,线程是安全的
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)