- LinkedList
- 数据存储是基于双向链表实现的
- 非线程安全
- 实现了Deque接口,双向队列,允许在队首、队尾进行入队和出队操作(Deque继承自Queue接口)
- 实现了Serializable接口,支持序列化,能够通过序列化传输,
- 实现了Cloneable接口,能被克隆。
- LinkedList 数据结构
- LinkedList类每个元素用内部类Node(结点)表示
- 每个结点除了数据域(item)之外,还有一个前指针(prev)和后指针(next),分别指向前驱结点和后继结点(如果有前驱/后继的话)。
- LinkedList通过first和last引用分别指向链表的第一个Node和最后一个Node,当链表为空时,first和last都为NULL值。
- LinkedList 添加元素
- 在链表头部添加
- 将当前新增节点的next指向first指向的节点
- 修改first指向,将其指向当前新增节点
- 修改之前first指向的节点的prev,将其指向当前新增节点
- 在链表尾部添加
- 将当前新增节点的prev指向last指向的节点
- 修改last指向,将其指向当前新增节点
- 修改之前last指向的节点的next,将其指向当前新增节点
- 在链表中间添加
- 先查找需要插入节点的位置(index)
- 如果插入位置(index)等于链表长度(size),则直接在链表尾部添加
- 否则获取待插入位置的节点(node-index)和它的prev节点(node-index-prev)
- 将新增节点(node-new)的prev和next分别指向节点(node-index-prev)和节点(node-index)
- 修改节点(node-index-prev)的next,将其指向当前新增节点(node-new)
- 修改节点(node-index) 的prev,将其指向当前新增节点 (node-new)
注:上面的操作都是操作的对象的引用,可以看出,LinkedList 新增或者删除元素,只要修改元素的引用就可以,不需要进行位置的移动,但是在查找指定位置的元素时则需要从链表头部开始查找
- LinkedList 的多线程环境下使用
// 1、使用Collections类中提供的静态工厂方法创建的同步容器类
// 注:此方法并非绝对同步,还会存在线程安全问题
List<String> linkedList = Collections.synchronizedList(new LinkedList<String>());
// 2、使用并发容器类
java.util.concurrent.ConcurrentLinkedQueue
- 简单集合关系图