当前位置:   article > 正文

2、Vector集合、Stack栈结构(了解)、LinkedList链表结构的特点的工作原理以及使用特点 以及解析集合中有序和无序_vector集合的特点

vector集合的特点

Vectoc

Vector:Vector是线程安全的、有序的、可重复的,可以通过设置capacityIncrement【增长因子】来设定扩容的次数,一般默认为0,也是默认两倍的扩容

Vector中有一个子类Stack,是一个栈结构的集合,工作原理是先进后出 后进先出

LinkedList:是链表结构的集合、物理地址上不是连续的,通过引用指针的形式进行关联【底层通过内部类Node来存储数据及前后节点的关联】
–有序的、可重复的

LinkedList:即实现了Dueue列的接口,也实现了List的接口,拥有了队列和List的功能

思考:LinkedList和ArrayList的区别
(1)性能:批量添加数据时ArrayList>LinkedList 但是涉及到索引的插入及修改操作时LinkedList>ArrayList
(2)LinkedList有对列的功能,ArrayList只有List的功能

使用场景:
单线程,不涉及频繁的修改操作【ArraysList】
单线程,涉及频繁的修改操作【LinedkList】
多线程【Vector】
栈结构【Stack】

Vector是线程安全的、有序的、可重复的,可以通过设置capacityIncrement【增长因子】来设定扩容的次数,一般默认为0,也是默认两倍的扩容

特点:线程安全的、有序的、可重复的
/**
 * @author Lantzrung
 * @date 2022年7月25日
 * @Description
 */
package com.day0725;

import java.util.Arrays;
import java.util.List;
import java.util.Vector;

public class VectorDemo {
    // Vector集合【有序的、可重复、线程安全、默认初始化为10,每次是扩容的2倍】
    public static void main(String[] args) {

	Vector list = new Vector();
	// 添加数据

	// OPEN1:
//	list.add("a");
//	list.add("b");
//	list.add("c");
//	list.add("d");
//	System.out.println(list);// [a, b, c, d]

	// OPEN2: // 证明了有序的
	// 注意这里的有序不是指不是排序,是指保留插入的顺序
//	list.add("a");
//	list.add("c");
//	list.add("b");
//	list.add("d");
//	System.out.println(list);// [a, c, b, d]

	// OPEN3: // 证明了vector可重复的
//	list.add("a");
//	list.add("b");
//	list.add("c");
//	list.add("d");
//	list.add("d");
//	System.out.println(list);// [a, b, c, d, d]

	// OPEN4:
	// public void addElement​(E obj)
	// 将指定的组件添加到此向量的末尾,将其大小增加1。 如果该载体的大小大于其容量,则该载体的容量增加。
//	List list = new Vector();
//      ((Vector) list).addElement("e");
	list.addElement("e");
	System.out.println(list);// [e]

	// 1、先打开Vector的源码,找到以下源码
//        public Vector() {
//        this(10);
//        }
//		
	// 2、然后打开 this(10); 发现它调用的是本身的另外一个构造器
//		public Vector(int initialCapacity) {
//		        this(initialCapacity, 0);
//		}

	// 3、然后再打开Vector(int initialCapacity)的this方法,然后发现
	// 它会进行判断如果initialCapacity(这里本身就是10的对象)要是小于0时会抛出一个异常,否则就会创建一个新的Object数组
//	    public Vector(int initialCapacity, int capacityIncrement) {
//	        super();
//	        if (initialCapacity < 0)
//	            throw new IllegalArgumentException("Illegal Capacity: "+
//	                                               initialCapacity);//IllegalArgumentException(非法参数异常)
//	        this.elementData = new Object[initialCapacity];
//	        this.capacityIncrement = capacityIncrement;
//	    }

	// 4、然后再搜索insert 找到以下源码这个方法是用于在Vector中插入那个元素
//		   public synchronized void insertElementAt(E obj, int index) { 
//		        modCount++;
//		        if (index > elementCount) {
//		            throw new ArrayIndexOutOfBoundsException(index
//		                                                     + " > " + elementCount);
//		        }
//		        ensureCapacityHelper(elementCount + 1);
//		        System.arraycopy(elementData, index, elementData, index + 1, elementCount - index);
//		        elementData[index] = obj;
//		        elementCount++;
//		    }

	// 5、然后在Vector的方法中查找add 找到以下源码
//	    public synchronized boolean add(E e) {// 添加的方法  使用了synchronized同步修饰符
	// 使用是在多线程并发的时候,确保一个时间点里面避免并发的一个异常,一个线程安全的操作
//	        modCount++;//计数++
//	        ensureCapacityHelper(elementCount + 1);//用于确保容量是足够的
//	        elementData[elementCount++] = e;//赋值操作
//	        return true;
//	    }

//		 public synchronized void addElement(E obj) {// 添加元素的方法
//		        modCount++;
//		        ensureCapacityHelper(elementCount + 1);
//		        elementData[elementCount++] = obj;
//		    }

	// 6、然后打开ensureCapacityHelper方法然后再打开grow(增长方法)
//		  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);//6、1如果capacityIncrement大于0,那么就赋值给capacityIncrement,否则就是赋值给oldCapacity。
	// 6、2再打开capacityIncrement的方法发现它一开始是为0的
//	        protected int capacityIncrement;
	// 6、3所以得出后面的三元运算符是执行运行后面的操作,是使用后面的来进行赋值oldCapacity
	// 故此得出 扩展因子是 int newCapacity = oldCapacity++oldCapacity;因此是两倍的扩容

//	        if (newCapacity - minCapacity < 0)
//	            newCapacity = minCapacity;
//	        if (newCapacity - MAX_ARRAY_SIZE > 0)
//	            newCapacity = hugeCapacity(minCapacity);
//	        elementData = Arrays.copyOf(elementData, newCapacity);
//	    }

	// 添加数据
//	list.addElement("e");
//	//
//	System.out.println(list);
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129

注意:这里的有序和无序不是指排序,而是qwq看下文解析

有序是指不是排序,是保留插入的顺序,就是保留插入数据的时候的顺序
无序也是不是指排序,是没有保留插入的顺序,是乱的

Stack,是一个栈结构的集合,工作原理是先进后出 后进先出

特点:栈结构的集合 先进后出 后进先出
/**
 * @author Lantzrung
 * @date 2022年7月27日
 * @Description
 */
package day0726;

import java.util.Stack;

public class StackDemo {
	public static void main(String[] args) {
		// 栈结构【具有栈的特点,也具有数组的特征】 -- List <-- Vector <-- Stack
		// 先进后出,后进先出 可以理解为手枪的【弹夹】
		Stack stack = new Stack();
		
		// 压栈
		stack.push("a");
		stack.push("b");
		stack.push("c");
		System.out.println(stack);//[a, b, c]

		// 出栈
		System.out.println(stack.peek());//c 获取栈顶元素但不移除
		System.out.println(stack);//[a, b, c]
		System.out.println(stack.pop());//c  获取栈顶元素但移除
		System.out.println(stack);//[a, b]

		//具有数组的特征 但是栈的话一般都是使用栈的特点
		stack.add("a");
		stack.addElement(stack);
	}

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

LinkedList是链表结构的集合、物理地址上不是连续的,通过引用指针的形式进行关联【底层通过内部类Node来存储数据及前后节点的关联】

有序的、可重复的
/**
 * @author Lantzrung
 * @date 2022年7月25日
 * @Description
 */
package com.day0725;

import java.util.LinkedList;

public class LinkedListDemo {
	public static void main(String[] args) {
		// LinkedList [链表结构、有序的、可重复的]
//		List list = new LinkedList();
//		// 1、LinkedList插入数据的方法
//		list.add("a");
//		list.add("b");
//		list.add("c");
//		list.add("d");
//		System.out.println(list);// [a, b, c, d]

		// 2、List list = new LinkedList();现在是通过父类的角度进行编译的,看不到子类的特 
// 征。
		// 所以我们把引用类型改为LinkedList即可看到子类的特征了
		// 当然也是可以不修改引用类型也可以执行子类的特征,只需要在调用方法前面加上强制类型 // 转换即可((LinkedList) list)
		LinkedList list = new LinkedList();
		list.add("a");
		list.add("b");
		list.add("c");
		list.add("d");
		System.out.println(list);// [a, b, c, d]
		// 2.1、LinkedList插入数据的方法
		list.addFirst("e");// 在头部插入数据
		list.addLast("e");// 在尾部插入数据
		System.out.println(list);// [e, a, b, c, d, e]
		// 2.2、删除头部和尾部数据
		list.removeFirst();// 删除头部数据
		list.removeLast();// 删除尾部数据
		System.out.println(list);// [a, b, c, d]

		// 3、链表结构有什么特点呢?
		// 打开LinkedLis的源码 发现以下列表
//		 public LinkedList() {
//		 }

//		transient Node<E> first;//开头
//      transient Node<E> list;//结尾

		// 3.1、再打开Node<E>
		// 然后我们发现新打开了一个文件,java.util.LinkedList$Node这是一个匿名内部类
		// 然后这个就是一个静态的类Node<E>
		// 图解的话每个节点之间都会有关联的通过Node<E>来进行引用,它不是同一个内存块里面的,它不也是连续的
//	    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;
//	        }
//	    }
      
		// 3.2、链表结构有什么好处?
		// 举例:如果我们要在一个数据里面插入一个item的数据
//      步骤1:  1 2 3 5 4 6 7 8 9 
//      步骤2:  1 2 3 5 4 6 7 8 9 我们得先把这个数据往后移n个单位
//		步骤3:  1 2 3 5 item 4 6 7 8 9 然后才会重新插入该数据 这个就是数组结构的做法
		// 而且随着数据的量越大,那么它的性能就越慢。这就是数组结构的
		
		// 3.3、那要是我们使用的是链表结构的话 
		// 看图解结合文字即可qwq
		// 1、要是我在中间插入一个数据
		// 2、那么就会添加一个新的节点
		// 3、把新的元素节点移上去赋值给前面的节点然后返回first;
		// 链表结构的性能比数组的性能要大,因为它的数据量比链表结构的要小。
		
     
		// 替换操作
//		list.set(index,element);

		// 根据索引获取数据
		// list.get(index);

	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87

3.1的图解
​​在这里插入图片描述

​​​​​​​​​​

–3.3的图解

​​在这里插入图片描述

​​
//总结就是:
// 1、数组而且随着数据的量越大,那么它的性能就越慢。这就是数组结构的
// 2、链表结构的性能比数组的性能要大,因为它的数据量比链表结构的要小。
// 3、链表结构和数组结构主要体现在于【插入和删除】

–LinkedList:即实现了Dueue列的接口,也实现了List的接口,拥有了队列和List的功能

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/322007
推荐阅读
相关标签
  

闽ICP备14008679号