集合03 Collection (List) - Java

ArrayList

ArrayList注意事项

  1. permits all elements, including null 。ArrayList 可以加入null,并且多个。
  2. ArrayList是由数组来实现数据存储的。
  3. ArrayList基本等同于Vector,除了ArrayList是线程不安全(执行效率高)看源码,在多线程情况下,不建议使用ArrayList。
    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类的定义说明
public class Vector<E>
    extends AbstractList<E>
    implements List<E>, RandomAccess, Cloneable, java.io.Serializable
  1. Vector底层也是一个对象数组 protected Object[] elementData;
  2. Vector是线程同步的,即线程安全,Vector类的操作方法带有synchronized
public synchronized E get(int index){
	if (index >= elementCount)
		throw new ArraylndexOutOfBoundsException(index);
		return elementData(index);
	}

4)在开发中,需要线程同步安全时,考虑使用Vector
在这里插入图片描述

——Vector和ArrayList比较

在这里插入图片描述

Vector底层结构和源码分析

//无参构造器
//有参数的构造
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

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查看源码学习


有很多种删除方式

linkedList.remove();//默认删除第一个节点


——LinkedList和ArrayList比较

在这里插入图片描述

本笔记是对韩顺平老师的Java课程做出的梳理。方便本人和观看者进行复习。
课程请见: https://www.bilibili.com/video/BV1fh411y7R8/?spm_id_from=333.999.0.0&vd_source=ceab44fb5c1365a19cb488ab650bab03

  • 13
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值