Arraylist与Vector的区别
Vector是jdk比较早中的集合类型,现在开发中已经不怎么用了,所以不需要研究太多,而ArrayList完全是对数组的替代,其中大部分常用的方法几乎和直接或间接实现的list接口和collection接口中一致。
ArrayList
Vector 区别
相同点:
1.底层都是采用数组进行数据存储 Object[]
2.有共同的父亲 AbstractList 都实现了接口list
不同点:
1.ArrayList创建对象时 没有给底层数组开辟空间 底层
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
Vector 在创建对象时 会给底层开辟长度为10 的数组
public Vector() { this(10); }
而 ArrayList 在添加对象时 给底层数组开辟空间 长度为10
private static final int DEFAULT_CAPACITY = 10;
2:扩容规则不同
ArrayList 扩容到原来的1.5倍
int newCapacity = oldCapacity + (oldCapacity >> 1);
private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; int newCapacity = oldCapacity + (oldCapacity >> 1); if (newCapacity - minCapacity < 0) newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); // minCapacity is usually close to size, so this is a win: elementData = Arrays.copyOf(elementData, newCapacity); }
Vector
int oldCapacity = elementData.length;//10
int newCapacity = oldCapacity + ((capacityIncrement > 0) ?capacityIncrement : oldCapacity);capacityIncrement:容量新增/增长因子 在创建对象时指定
增张因子可以在构造器中在创建对象的时候进行设置( new Vector<>(30,40);)
如果capacityIncrement <=0 扩容到原来的2倍
如果capacityIncrement > 0 扩容到 oldCapacity+capacityIncrementprivate void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; int newCapacity = oldCapacity + ((capacityIncrement > 0) ? capacityIncrement : oldCapacity); if (newCapacity - minCapacity < 0) newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); elementData = Arrays.copyOf(elementData, newCapacity); }
3.线程安全问题
Vector 线程安全的 效率低
ArrayList 线程不安全 效率高4.版本问题
ArrayList 1.2
Vector 1.0
LinkedList:双向链表 双向循环链表
public class LinkedListTest {
/*
LinkedList 相较于 List 新增的方法
*/
@Test
public void test02(){
//对象创建完毕
LinkedList<String> list = new LinkedList<>();
list.add("张三");
list.add("李四");
list.add("王五");
System.out.println(list);//[张三, 李四, 王五]
System.out.println("list.getFirst() = " + list.getFirst());
System.out.println("list.getLast() = " + list.getLast());
list.addFirst("安琪拉");
list.addLast("嬴政");
System.out.println(list);//[安琪拉, 张三, 李四, 王五, 嬴政]
list.removeFirst();
System.out.println(list);//[张三, 李四, 王五, 嬴政]
list.removeLast();
System.out.println(list);//[张三, 李四, 王五]
}
@Test
public void test01(){
//对象创建完毕
LinkedList<String> list = new LinkedList<>();
list.add("张三");
list.add("李四");
list.add("王五");
}
}
LinkedList类中的成员变量
长度 以及维护了前后两个节点,使得其有序
transient int size = 0;
transient Node<E> first;
transient Node<E> last;
Node类属于LinkedList类的成员内部类
private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;
Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
画图的时候最好使用地址值,不要老是使用箭头,否则会指向不清晰
LinkedList 相较于 List 新增的方法
分析:linkedlist底层使用双向链表进行存储,因此新增的方法也都是与链表有关系的(另外双向链表增加删除快但是查询和更改的时候相对于数组慢,所以在使用的时候,根据不同的应用场景,选择使用ArrayList还是LinkedList)
增 addFirst(ele) addLast(ele);
删 removeFirst() removeLast();
改
查 getFirst() getLast()
模拟栈和队列的方法 peek() poll()
push() pop() peek()
栈:
FILO first in last out刷盘子
入栈: 向栈中添加元素出栈: 将栈顶元素弹出
入栈和出栈 都是【相对】栈顶元素而言
队列:(queue 一个出口 deque 两个出口双端队列两端访问元素的方法)
队头删除
队尾添加
Deque模拟栈(打印的顺序从栈顶到栈底 更加形象)
@Test
public void test01(){
Deque<String> stack = new LinkedList<>();
//入栈 出栈的时候倒着出
stack.push("001");
stack.push("002");
stack.push("003");
stack.push("004");
stack.push("005");
System.out.println("stack = " + stack);
//弹栈
String pop1 = stack.pop();
System.out.println("pop1 = " + pop1);
//获取栈顶元素
String peek = stack.peek();
System.out.println("peek = " + peek);
}
有stack类,但是queue和deque都是接口
Stack类的测试(同样的代码) 打印的顺序按添加的顺序
public void test02(){
Stack<String> stack = new Stack<>();
stack.push("001");
stack.push("002");
stack.push("003");
stack.push("004");
stack.push("005");
System.out.println("stack = " + stack);
//弹栈
String pop1 = stack.pop();
System.out.println("pop1 = " + pop1);
//获取栈顶元素
String peek = stack.peek();
System.out.println("peek = " + peek);
}
LinkedList模拟队列
@Test
public void test03(){
Queue<String> queue = new LinkedList<>();
queue.add("001");
queue.add("002");
queue.add("003");
queue.add("004");
queue.add("005");
System.out.println("queue = " + queue);
/* queue.remove();
queue.remove();
queue.remove();
queue.remove();
queue.remove();
System.out.println("queue = " + queue);*/
/*queue.poll();
queue.poll();
queue.poll();
queue.poll();
queue.poll();
System.out.println("queue = " + queue);*/
String peek = queue.peek();
System.out.println("peek = " + peek);
}
@Test
public void test02(){
Stack<String> stack = new Stack<>();
stack.push("001");
stack.push("002");
stack.push("003");
stack.push("004");
stack.push("005");
System.out.println("stack = " + stack);
//弹栈
String pop1 = stack.pop();
System.out.println("pop1 = " + pop1);
//获取栈顶元素
String peek = stack.peek();
System.out.println("peek = " + peek);
}