Java数据结构-List相关

1:ArrayList

在这里插入图片描述

底层数据结构:ArrayList的底层为数组

使用注意点: ArrayList插入数据要确保前一个位置有数据。

ArrayList的遍历方式有三种:for循环,forEach,迭代器

	ArrayList<Object> arrayList=new ArrayList<>();
        arrayList.add(1);
        arrayList.add(2);
        arrayList.add(3);
        arrayList.add(4);
        //for循环
        for (int i = 0; i < arrayList.size(); i++) {
            System.out.println(arrayList.get(i));
        }
        //foreach
        for (Object o : arrayList) {
            System.out.println(o);
        }
        //迭代器
        Iterator<Object> iterator = arrayList.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }

ArrayList的扩容机制(源码分析):

  1. 无参构造后:默认数组长为0
  2. 第一次使用add,数组长为10
  3. 此后每次扩容1.5倍,若1.5倍不够则直接扩容到想要的大小
  4. 带参构造给多少初始化大小为多少
ArrayList<Object> arrayList=new ArrayList<>();
        arrayList.add(1);

无参构造:

//ArrayList源码
public ArrayList() {
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;}
//可以看到无参构造器创建了一个长度为0的Object类型数组
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
//第一次插入数据时
public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // 此时size为0
        elementData[size++] = e;
        return true;}
//调用ensureCapacityInternal(1)方法
 private void ensureCapacityInternal(int minCapacity) {//minCapacity=1
        ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));}
//又调用了calculateCapacity(Object数组,1)方法
private static int calculateCapacity(Object[] elementData, int minCapacity) {
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            return Math.max(DEFAULT_CAPACITY, minCapacity);
        }
        return minCapacity;}
//可以看到DEFAULT_CAPACITY为10,所以这里返回10
private static final int DEFAULT_CAPACITY = 10;
//调用ensureExplicitCapacity(10)方法
 private void ensureExplicitCapacity(int minCapacity) {
        modCount++;
        // overflow-conscious code
     //这里判断传递的参数minCapacity和底层数组长度相减是否大于0,如果大于0则调用grop方法且将minCapacity作为参数
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);}
//看看grop方法
  private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;//这里定义oldCapacity为底层数组长度
        int newCapacity = oldCapacity + (oldCapacity >> 1);//可看到newCapacity为1.5倍旧的长度
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;//如果扩容后能不够满足minCapacity的大小,则新的容量为minCapacity
        if (newCapacity - MAX_ARRAY_SIZE > 0)//如果newCapacity大于MAX_ARRAY_SIZE
            newCapacity = hugeCapacity(minCapacity);//调用hugeCapacity参数为minCapacity
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);
    }
//MAX_ARRAY_SIZE大小为Integer.MAX_VALUE - 8
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
//hugeCapacity方法
  private static int hugeCapacity(int minCapacity) {
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError();
        return (minCapacity > MAX_ARRAY_SIZE) ?
            Integer.MAX_VALUE :
            MAX_ARRAY_SIZE;}//minCapacity的值大于MAX_ARRAY_SIZE则赋值为Integer.MAX_VALUE,不大于MAX_ARRAY_SIZE赋值为MAX_ARRAY_SIZE

有参构造:

 public ArrayList(int initialCapacity) {
        if (initialCapacity > 0) {
            this.elementData = new Object[initialCapacity];
        } else if (initialCapacity == 0) {
            this.elementData = EMPTY_ELEMENTDATA;
        } else {
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        }
    }

2:LinkedList

在这里插入图片描述

底层数据结构:LinkedList底层为双向链表,双向链表结点为Date(数据),prev(前驱),next(后继)

为什么引入LinkedList?

ArrayList每次指定位置添加或删除会进行移动元素操作,如果存在大量的添加删除很不方便。

链表: 逻辑上连续,物理地址上非连续

LinkedList的遍历:

List<Integer> list=new LinkedList<>();

        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);

        for(int i=0;i<list.size();i++){
            System.out.print(list.get(i));
        }

        for(Integer i:list){
            System.out.print(i);
        }

        Iterator<Integer> iterator = list.iterator();
        while (iterator.hasNext()){
            System.out.print(iterator.next());
        }

        //逆序输出
        ListIterator<Integer> integerListIterator = list.listIterator(list.size());
        while (integerListIterator.hasPrevious()){
            System.out.print(integerListIterator.previous());
        }

3:ArrayLsit和LinkedList的区别

顺序表:适合频繁访问元素

链表:适合频繁插入删除元素

不同点ArrayLsitLinkedList
存储空间物理上连续逻辑上连续,物理上不一定连续
随机访问支持随机访问,时间复杂度为O(1)不支持随机访问,需要遍历,时间复杂度为O(N)
头插法需要移动元素,时间复杂度O(N)修改引用指向,时间复杂度O(1)
插入空间不够需要扩容无容量概念
应用场景元素高效存储且频繁访问任意位置的插入和删除频繁

4:栈

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4AJQcNXK-1652540036712)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20220514223337245.png)]

栈的底层数据结构:数组

栈的特性:先进后出

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qUZO13tK-1652540036713)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20220514223450943.png)]

push:入栈
pop:弹出栈顶元素并从栈中删除
peek:获取栈顶元素但不删除
empty:是否为空
search:距离栈顶的长度,栈顶元素距离为1

栈,虚拟机栈,栈帧区别:

  1. 栈:数据结构
  2. 虚拟机栈:JVM内存
  3. 栈帧:当运行函数时,会在Java虚拟机栈上开辟栈帧给当前函数

5:队列

public interface Queue<E> extends Collection<E> 

队列特性:先进先出

在这里插入图片描述

add:插入元素,但是如果队列为空则抛出异常
offer:插入元素,队列为空不会抛出异常
remove:移除队列头部元素,但是如果队列为空则抛出异常
poll:移除队列头部元素,队列为空不会抛出异常
element:将队列头部元素的值返回,但是如果队列为空则抛出异常
peek:将队列头部元素的值返回,队列为空不会抛出异常

实例化:以LinkedList为例,只能使用Queue特有方法或者LinkedList重写的方法。

Queue<Integer> queue=new LinkedList<>();
PriorityQueue:优先级队列,基于小根堆,请关注后续堆的内容
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值