赞
踩
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】
/** * @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); } }
有序是指不是排序,是保留插入的顺序,就是保留插入数据的时候的顺序
无序也是不是指排序,是没有保留插入的顺序,是乱的
/** * @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); } }
/** * @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); } }
3.1的图解
–3.3的图解
//总结就是:
// 1、数组而且随着数据的量越大,那么它的性能就越慢。这就是数组结构的
// 2、链表结构的性能比数组的性能要大,因为它的数据量比链表结构的要小。
// 3、链表结构和数组结构主要体现在于【插入和删除】
–LinkedList:即实现了Dueue列的接口,也实现了List的接口,拥有了队列和List的功能
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。