集合03 Collection (List) - Java

List

ArrayList

ArrayList注意事项

  1. permits all elements, including null 。ArrayList 可以加入null,并且多个。
  2. ArrayList是由数组来实现数据存储的。
  3. ArrayList基本等同于Vector,除了ArrayList是线程不安全(执行效率高)看源码,在多线程情况下,不建议使用ArrayList。
java 复制代码
    public static void main(String[] args) {
        ArrayList arrayList = new ArrayList();
        arrayList.add(null);
        arrayList.add(2);
        arrayList.add(null);
        arrayList.add("hello");
        System.out.println(arrayList);
    }


ArrayList底层操作机制-源码分析(重点)

  1. ArrayList中维护了一个Object类型的数组elementData。[debug看源码] transient Object[] elementData;
    transient表示瞬间,短暂的。表示该属性不会被序列化/串行化。
  2. 当创建ArrayList对象时,如果使用的是无参构造器,则初始elementData容量为0,第1次添加,则扩容elementData为10,如需要再次扩容,则扩容elementData为1.5倍。
  3. 如果使用的是指定大小的构造器,则初始elementData容量为指定大小,如果需要扩容,则直接扩容 elementData为1.5倍。

点击链接跳转看韩顺平老师的视频讲解

注意,IDEA 默认情况下,Debug 显示的数据是简化后的,如果希望看到完整的数据需要做设置。

Vector

Vector基本介绍

import java.util.Vector;

  1. Vector类的定义说明
java 复制代码
public class Vector<E>
    extends AbstractList<E>
    implements List<E>, RandomAccess, Cloneable, java.io.Serializable
  1. Vector底层也是一个对象数组 protected Object[] elementData;
  2. Vector是线程同步的,即线程安全,Vector类的操作方法带有synchronized
java 复制代码
public synchronized E get(int index){
	if (index >= elementCount)
		throw new ArraylndexOutOfBoundsException(index);
		return elementData(index);
	}

4)在开发中,需要线程同步安全时,考虑使用Vector

------Vector和ArrayList比较

Vector底层结构和源码分析

java 复制代码
//无参构造器
//有参数的构造
Vector vector = new Vector();
for (int i = 0; i < 10; i++) {
    vector.add(i);
}
vector.add(100);
System.out.println("vector=" + vector);
1. new Vector() 底层
   public Vector() {
       this(10);
   }
补充:如果是  Vector vector = new Vector(8);
   走的方法:
   public Vector(int initialCapacity) {
       this(initialCapacity, 0);
   }
其中有一个装箱过程
2. vector.add(i)
2.1  //下面这个方法就添加数据到vector集合
   public synchronized boolean add(E e) {
       modCount++;
       ensureCapacityHelper(elementCount + 1);
       elementData[elementCount++] = e;
       return true;
   }
 2.2  //确定是否需要扩容 条件 : minCapacity - elementData.length>0
   private void ensureCapacityHelper(int minCapacity) {
       // overflow-conscious code
       if (minCapacity - elementData.length > 0)
           grow(minCapacity);
   }
 2.3 //如果 需要的数组大小 不够用,就扩容 , 扩容的算法
     //newCapacity = oldCapacity + ((capacityIncrement > 0) ?
     //                             capacityIncrement : oldCapacity);
     //就是扩容两倍.
   private 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);
   }

LinkedList

基本介绍

  1. LinkedList底层实现了双向链表和双端队列特点
  2. 可以添加任意元素(元素可以重复),包括null
  3. 线程不安全,没有实现同步

LinkedList的底层结构和操作机制

  1. LinkedList底层维护了一个双向链表
  2. LinkedList中维护了两个属性 first和 last分别指向首节点和尾节点
  3. 每个节点(Node对象),里面又维护了prev、next、item三个属性,其中通过 prev指向前一个,通过 next指向后一个节点。最终实现双向链表
  4. 所以 LinkedList的元素的添加和删除,不是通过数组完成的,相对来说效率较高
  5. 模拟一个简单的双向链表代码【代码】

见LinkedList01.java

LinkedList的增删改查

见LinkedListCRUD.java

java 复制代码
public static void main(String[] args) {

      LinkedList linkedList = new LinkedList();
      linkedList.add(1);
      linkedList.add(2);
      linkedList.add(3);
      System.out.println("linkedList=" + linkedList);

      //演示一个删除结点的
      linkedList.remove(); // 这里默认删除的是第一个结点
      //linkedList.remove(2);

      System.out.println("linkedList=" + linkedList);

      //修改某个结点对象
      linkedList.set(1, 999);
      System.out.println("linkedList=" + linkedList);

      //得到某个结点对象
      //get(1) 是得到双向链表的第二个对象
      Object o = linkedList.get(1);
      System.out.println(o);//999

      //因为LinkedList 是 实现了List接口, 遍历方式
      System.out.println("===LinkeList遍历迭代器====");
      Iterator iterator = linkedList.iterator();
      while (iterator.hasNext()) {
          Object next =  iterator.next();
          System.out.println("next=" + next);

      }

      System.out.println("===LinkeList遍历增强for====");
      for (Object o1 : linkedList) {
          System.out.println("o1=" + o1);
      }
      System.out.println("===LinkeList遍历普通for====");
      for (int i = 0; i < linkedList.size(); i++) {
          System.out.println(linkedList.get(i));
      }
}

debug查看源码学习

有很多种删除方式

java 复制代码
linkedList.remove();//默认删除第一个节点


------LinkedList和ArrayList比较

本笔记是对韩顺平老师的Java课程做出的梳理。方便本人和观看者进行复习。

课程请见: https://www.bilibili.com/video/BV1fh411y7R8/?spm_id_from=333.999.0.0\&vd_source=ceab44fb5c1365a19cb488ab650bab03

相关推荐
m0_571957581 小时前
Java | Leetcode Java题解之第543题二叉树的直径
java·leetcode·题解
魔道不误砍柴功3 小时前
Java 中如何巧妙应用 Function 让方法复用性更强
java·开发语言·python
NiNg_1_2343 小时前
SpringBoot整合SpringSecurity实现密码加密解密、登录认证退出功能
java·spring boot·后端
闲晨3 小时前
C++ 继承:代码传承的魔法棒,开启奇幻编程之旅
java·c语言·开发语言·c++·经验分享
测开小菜鸟4 小时前
使用python向钉钉群聊发送消息
java·python·钉钉
P.H. Infinity5 小时前
【RabbitMQ】04-发送者可靠性
java·rabbitmq·java-rabbitmq
生命几十年3万天5 小时前
java的threadlocal为何内存泄漏
java
caridle6 小时前
教程:使用 InterBase Express 访问数据库(五):TIBTransaction
java·数据库·express
^velpro^6 小时前
数据库连接池的创建
java·开发语言·数据库
苹果醋36 小时前
Java8->Java19的初步探索
java·运维·spring boot·mysql·nginx