67.Vector
-
Vector底层也是一个对象数组,protected Object[] elementData;
-
Vector是线程同步的,即线程安全,Vector类的操作方法带有synchronized
-
在开发中,需要线程同步时,考虑Vector
Vector和ArrayList的比较
68.LinkedList
-
LinkedList实现了双向链表和双端列队特点
-
可以添加任意元素(元素可以重复),包括null
-
线程不安全,没有实现同步
LinkedList的底层操作机制
-
LinkedList底层维护了一个双向链表
-
LinkedList中维护了两个属性first和last分别指向首节点和尾节点
-
每个节点(Node对象),里面又维护了prev、next、item三个属性,其中通过prev指向前一个,通过next指向后一个节点。最终实现双向链表
-
所以LinkedList的元素的添加和删除,不是通过数组完成的,相对来说效率较高
双向链表模拟:
public class HelloJava { public static void main(String[] args) { //模拟一个简单的双向链表 Node jack = new Node("jack"); Node tom = new Node("tom"); Node jerry = new Node("jerry"); //连接三个节点,形成双向链表 //jack -> tom -> jerry jack.next = tom; tom.next = jerry; //jerry -> tom -> jack jerry.pre = tom; tom.pre = jack; Node first = jack;//让first引用指向jack,就是双向链表的头节点 Node last = jerry;//让last引用指向jerry,就是双向链表的尾节点 //演示,从头到尾进行遍历 System.out.println("=====从头到尾遍历====="); while (true){ if (first == null){ break; } //输出first信息 System.out.println(first); first = first.next; } //演示,从尾到头遍历 System.out.println("=====从尾到头遍历====="); while (true){ if (last == null){ break; } //输出first信息 System.out.println(last); last = last.pre; } //演示链表的添加对象/数据 十分方便 //在tom和jerry中插入一个对象smith //1.先创建一个Node节点,name就是smith Node smith = new Node("smith"); smith.next = jerry; smith.pre = tom; jerry.pre = smith; tom.next = smith; //让first再次指向jack first = jack; System.out.println("=====从头到尾遍历====="); while (true){ if (first == null){ break; } //输出first信息 System.out.println(first); first = first.next; } } } //定义一个Node类,Node对象,表示双向链表的一个节点 class Node{ public Object item;//真正存放数据 public Node next;//指向下一个节点 public Node pre;//指向上一个节点 public Node(Object name){ this.item = name; } public String toString(){ return "Node name=" + item; } }
69.List集合选择
ArrayList和LinkedList的比较
如何选择ArrayList和LinkedList:
-
如果我们改查的操作多,选择ArrayList
-
如果我们增删的操作多,选择LinkedList
-
一般来说,在程序中,80%~90%都是查询,因此大部分情况选择ArrayList
-
在一个项目中,根据业务灵活选择。可能一个模块是用的ArrayList,另一个模块用的LinkedList