java基础之ArrayList和Vector的主要区别;
List接口下一共实现了三个类:ArrayList,Vector,LinkedList。
LinkedList主要保持数据的插入顺序的时候使用,采用链表结构。
ArrayList,Vector主要区别为以下几点:
(1):Vector是线程安全的,源码中有很多的synchronized可以看出,而ArrayList不是。导致Vector效率无法和ArrayList相比;
(2):ArrayList和Vector都采用线性连续存储空间,当存储空间不足的时候,ArrayList默认增加为原来的50%,Vector默认增加为原来的一倍;
(3):Vector可以设置capacityIncrement,而ArrayList不可以,从字面理解就是capacity容量,Increment增加,容量增长的参数。
源码分析:
首先看看构造器:
ArrayList:三个
/**
* Constructs an empty list with an initial capacity of ten.
* 构造一个默认初始容量为10的list
*/
public ArrayList() {
super();
this.elementData = EMPTY_ELEMENTDATA;
}
/**
* 构造一个指定默认长度的list initialCapacity 不能小于0;
* Constructs an empty list with the specified initial capacity.
*
* @param initialCapacity the initial capacity of the list
* @throws IllegalArgumentException if the specified initial capacity
* is negative
*/
public ArrayList(int initialCapacity) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
this.elementData = new Object[initialCapacity];
}
/** 构造一个包含collection 元素的list
* 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 ArrayList(Collection<? extends E> c) {
...
}
· 1
Vector:四个
//构造一个指定默认长度的list
public Vector(int initialCapacity) {
this(initialCapacity, 0);
}
//构造一个默认初始容量为10的list
public Vector() {
this(10);
}
//构造一个包含collection 元素的list
public Vector(Collection<? extends E> c) {
...
}
//区别在于可以设置capacityIncrement
public Vector(int initialCapacity, int capacityIncrement) {
super();
...
}
vector多了一个public Vector(int initialCapacity, int capacityIncrement)构造器,可以设置容量增长,arraylist是没有的。
主要添加源码分析
ArrayList类:
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
private void ensureCapacityInternal(int minCapacity) {
modCount++;
// overflow-conscious code
//如果添加一个元素之后,新容器的大小大于容器的容量,那么就无法存值了,需要扩充空间
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1); //扩充的空间增加原来的50%(即是原来的1.5倍)
if (newCapacity - minCapacity < 0) //如果容器扩容之后还是不够,那么干脆直接将minCapacity设为容器的大小
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0) //如果扩充的容器太大了的话,那么就执行hugeCapacity
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
Vector类:
public synchronized boolean add(E e) {
modCount++;
ensureCapacityHelper(elementCount + 1);
elementData[elementCount++] = e;
return true;
}
private void ensureCapacityHelper(int minCapacity) {
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
capacityIncrement : oldCapacity);
/**
这个扩容需要做个判断:如果容量增量初始化的不是0,即使用的public Vector(int initialCapacity,int capacityIncrement)
构造方法进行的初始化,那么扩容的容量是(oldCapacity+capacityIncrement),就是原来的容量加上容量增量的值;
如果没有设置容量增量,那么扩容后的容量就是(oldCapacity+oldCapacity),就是原来容量的二倍。
**/
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
elementData = Arrays.copyOf(elementData, newCapacity);
}
深入理解ArrayList与LinkedList的区别
一、先来看看ArrayList与LinkedList 在JDK中所在的位置
从图中可以看出,ArrayList与LinkedList都是List接口的实现类,因此都实现了List的所有未实现的方法,只是实现的方式有所不同,(编程思想: 从中可以看出面向接口的好处, 对于不同的需求就有不同的实现!),而List接口继承了Collection接口,Collection接口又继承了Iterable接口,因此可以看出List同时拥有了Collection与Iterable接口的特性.
二、认识和理解ArrayList
ArrayList实现了List接口,它是以数组的方式来实现的,数组的特性是可以使用索引的方式来快速定位对象的位置,因此对于快速的随机取得对象的需求,使用ArrayList实现执行效率上会比较好.
ArrayListDemo:
Java代码
1. public class ArrayListDemo {
2.
3. public static void main(String[] args) {
4.
5. List<String> userlist = new ArrayList<String>();
6. userlist.add("yulon");
7. userlist.add("xiaoyun");
8. userlist.add("羽龙共舞");
9. System.out.println("使用普通for循环:");
10. for(int i=0; i<userlist.size(); i++){
11. System.out.print(userlist.get(i)+" ");
12. }
13. System.out.println();
14. System.out.println();
15. System.out.println("使用Iterator迭代器:");
16. Iterator it = userlist.iterator();
17. while(it.hasNext()){
18. System.out.print(it.next()+" ");
19. }
20. System.out.println();
21. System.out.println();
22. System.out.println("使用增强for循环:");
23.
24. for(String s : userlist){
25. System.out.print(s+" ");
26. }
27. }
28. }
这里列举出了循环List列表的三种方式: 使用普通for循环,用get方法获取; 使用Iterator迭代器,使用next方法遍历;使用增强for循环,直接输出! 由此可见第三种方法是最方便,最简洁的!
三、认识和理解LinkedList
LinkedList是采用链表的方式来实现List接口的,它本身有自己特定的方法,如: addFirst(),addLast(),getFirst(),removeFirst()等. 由于是采用链表实现的,因此在进行insert和remove动作时在效率上要比ArrayList要好得多!适合用来实现Stack(堆栈)与Queue(队列),前者先进后出,后者是先进先出.
1、堆栈
Java代码
1. public class StringStack {
2. private LinkedList<String> linkedList
3. = new LinkedList<String>();
4.
5. /**
6. * 将元素加入LinkedList容器
7. * (即插入到链表的第一个位置)
8. */
9. public void push(String name){
10. linkedList.addFirst(name);
11. }
12. /**
13. * 取出堆栈中最上面的元素
14. * (即取出链表linkedList的第一个元素)
15. * @return
16. */
17. public String getTop(){
18. return linkedList.getFirst();
19. }
20. /**
21. * 取出并删除最上面的元素
22. * (即移出linkedList的第一个元素)
23. * @return
24. */
25. public String pop(){
26. return linkedList.removeFirst();
27. }
28. /**
29. * 获取元素个数
30. * @return
31. */
32. public int size(){
33. return linkedList.size();
34. }
35.
36. /**
37. * 判断堆栈是否为空
38. * (即判断 linkedList是否为空)
39. * @return
40. */
41. public boolean isEmpty(){
42. return linkedList.isEmpty();
43. }
44. //测试
45. public static void main(String[] args) {
46. StringStack stack = new StringStack();
47. stack.push("yulon");
48. stack.push("xiaoyun");
49. stack.push("羽龙共舞");
50. System.out.print("第一个元素是:\t");
51. System.out.println(stack.getTop());
52. System.out.println();
53. System.out.println("全部元素:");
54. while(!stack.isEmpty()){
55. System.out.println("\t"+stack.pop());
56. }
57. }
58. }
输出结果是:
Xml代码
1. 第一个元素是: 羽龙共舞
2.
3. 全部元素:
4. 羽龙共舞
5. xiaoyun
6. yulon
知识提示: LinkedList的特有方法(本身定义的方法)如:addFirst()、addLast()、getFirst()、getLast()、removeFirst()、removeLast()等
2、实现队列类似,在此不再举例
3、如果要使用队列的功能,由于LinkedList也实现了java.util.Queue接口,所以可以直接使用LinkedList的实例来实现.
Java代码
1. public class QueueDemo {
2. public static void main(String[] args) {
3. //父类引用queue指向子类对象
4. Queue<String> queue = new LinkedList<String>();
5. //offer()方法是往队列加入元素
6. queue.offer("xiaoyun");
7. queue.offer("yulon");
8. queue.offer("羽龙共舞");
9. String element = null;
10. while((element=queue.poll())!=null){
11. System.out.println(element+"\t");
12. }
13. }
14. }
输出顺序是:
Xml代码
1. xiaoyun
2. yulon
3. 羽龙共舞
四、在删除可插入对象的动作时,为什么ArrayList的效率会比较低呢?
解析: 因为ArrayList是使用数组实现的,若要从数组中删除或插入某一个对象,需要移动后段的数组元素,从而会重新调整索引顺序,调整索引顺序会消耗一定的时间,所以速度上就会比LinkedList要慢许多. 相反,LinkedList是使用链表实现的,若要从链表中删除或插入某一个对象,只需要改变前后对象的引用即可!
https://www.bookstack.cn/books/The-Linux-Command-Line
创建文件夹:mkdir 文件夹名
安装软件:yum install 软件包名
卸载软件:yum remove 软件包名
下载文件:weget 资源的url