List常见实现ArrayList,LinkedList,Vector及其对应底层实现

List常见实现由ArrayList,LinkedList,Vector

List是一个接口,它继承与Collection接口,代表它是有序的(即按照存入顺序遍历),
List与Set的区别:
1)List是有序的,是可以重复的
2)Set是无序的,是不可用重复的

ArrayList,LinkedList与Vector之间的区别:
1)ArrayList与Vector是用数组来实现的,LinkedList使用链表来实现
2)ArrayList不是线程安全的,而Vector使用锁(synchronized)来保证线程安全
3)ArrayList可用通过下标来直接访问数据,因此查找与更新较快,而LinkedList插入与删除较快同时,LinkedList还实现了Queue接口,所以他还提供了offer(), peek(), poll()等方法。
4)ArrayList扩容Vector扩容是不一样的,简单来说就是,当数组需要的长度大于数组的实际长度时,ArrayList扩展后数组大小为((原数组长度*3)/2+1)与传递参数中较大者,而Vector当扩容因子大于0时,新数组长度为原数组长度+扩容因子,否则新数组长度为原数组长度的2倍,将上面生成的新数组长度与传递的参数要求长度作比较,较大者为最终的新长度。
详细看ArrayList和Vector的扩容机制

ArrayList

学习自深入分析java集合ArrayList(源码分析)
ArrayList继承了AbstractList抽象类,实现了List,RandomAccess[随机访问],Cloneable[可克隆], java.io.Serializable[序列化,支持序列化,能通过序列化去传输]这些接口。
注意:ArrayList不是线程安全的,如果在多线程下,建议使用Vector或者CopyOnWriteArrayList。

为什么ArrayList不是线程安全的?
因为在add方法中,elementData[size++] = e,elementData与size都是全局变量,但没有进行sychronization同步处理,线程A执行了ArrayList的add方法,由于线程B获取到的size大小和线程A是一样的,此时的size大小应该是比原来的size要大1,但是B线程不知,所以B线程进行赋值的时候把A线程的值给覆盖,导致添加到数组中元素的个数其实是比逻辑上要少的。

如何解决线程不安全?
List list1 = Collections.synchronizedList(new ArrayList());
List list1 = new Vector();
List lsit1 = new CopyOnWriteArrayList();

构造方法
ArrayList():构造一个初始容量为10的空列表
ArrayList(Collection<?extend E> c):构造一个包含指定元素的列表
ArrayList( int initialCapcity ):构造一个具有初始容量值的空列表

添加方法:
add(E e):添加一个元素到列表的末尾。
add( int index, E element ) :在指定的位置添加元素
addAll( Collection<? extends E> c ):添加一个集合到元素的末尾.以上返回类型是boolean

1)add(E e)源码过程:
检查加入元素后的数组长度是否超过数组长度ensureCapacityInternal(size + 1),如果超过,则扩容为(原数组长度*3)/2+1)与传递参数中较大者,

2)add( int index, E element ) 源码过程:
检查index是否在0到size之间,可以为0和size,检查加入元素后需要扩容否,不够扩容,将数据从index开始后面的往后移一个,再将element赋值给elementData[index].

删除操作

remove(Object o):删除列表中第一个出现O的元素
remove( int index):删除列表中指定位置的元素
removeAll(Collection<?> c):删除列表中包含C的所有元素
removeIf(Predictcate<? super E> filter):删除列表中给定谓词的所有元素
removeRange( int from,int to ):删除从from到to的所有元素
clear():清除所有的元素。返回类型为void

remove( int index)源码分析:
检查index范围,如果大于size抛出异常,获得下标index的值,将后面的值前移,返回删除的值。

更改操作

retainAll( Collection<?> c ):仅仅保留列表中和C相同的元素,相当于&运算
set(int index,E element):用element替换index位置上的元素。
size():返回此列表的元素数
sort(Comparator<? super E> c):按照指定的排序规则排序
subList( int from , int to ):返回从from到to之间的列表
toArray():将列表转化为数组
trimToSize( ):修改当前实例的容量是列表的当前大小。

set(int index,E element)源码分析:
检查index范围,如果大于size抛出异常,获得下标index的值,修改值并返回原来的值

toArray的用法
在这里插入图片描述
查操作

contains(Object o):如果包含元素o,则返回为true
get(int index):返回指定索引的元素
indexOf( Object o ):返回此列表中指定元素的第一次出现的索引,如果列表不包含此元素,返回-1
lastindexOf( Object o ):返回此列表中指定元素的最后一次出现的索引,如果列表不包含此元素,返回-1
isEmpty():如果列表为空,返回true.
iterator():返回列表中元素的迭代器
listIterator():返回列表的列表迭代器(按适当的顺序)
listIterator(int index):从适当的位置返回列表的列表迭代器(按照正确的顺序)

常用遍历方法
在这里插入图片描述

LinkedList

学习自java集合之LinkedList详解
LinkedList底层为双向链表,间接的实现了List接口(说明LinkedList是有list的特性的,add,remove等)、实现了Cloneable(可复制)、Serializable(进行了序列化),除此之外还有一个东西还实现了Queue(队列,说明应该是有队列的一些特性,pop等)。

重要变量:
transient int size = 0;长度
transient Node first;链表的头
transient Node last;链表的尾
private static class Node {
E item;
Node next;
Node prev;

    Node(Node<E> prev, E element, Node<E> next) {
        this.item = element;
        this.next = next;
        this.prev = prev;
    }
}

链表维护了一个size、first(头)和last(尾),我们可以看到Node的结构中有个item、next、prev充分说明了此链表是一个双向链表。

add(E e)方法源码分析
取出last节点为l,将newNode的prev指向last节点,next指向null,然后将last指向newNode,如果链表为null,则first指向newNode,否则,将l的next指向newNode,size++。

remove(int index)源码分析
先检查index的范围,不在范围内则抛出异常,然后要找到这个下标,Java用index和size>>1比较,即index和size的一半比较,如果index小,则从first找起,如果index大,则从last找起。

Vector

Vector和ArrayList相似,内部都是一个可以动态增长的数组来实现的,不同点是Vector是线程安全的,其内部有很多同步代码块来实现线程安全。
Vector 继承了AbstractList,实现了List接口。Vector实现了RandmoAccess接口,即提供了随机访问功能。Vector 实现了Cloneable接口,即实现克隆功能。Vector 实现Serializable接口,表示支持序列化。
学习自Vector线程安全,ArrayList非线程安全

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值