查看ArrayList源码做的笔记

本文深入探讨了ArrayList的工作原理,包括其内部实现机制、随机访问特性及排序算法应用等关键信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.ArrayList

在这里插入图片描述

先了解两种访问方式,随机访问顺序访问

顺序访问:在一组长度为n的数据中,要找到其中的第i个元素,只能从头到尾的遍历,直到找到第i个元素。

就是遍历地查询我想要的元素呗。

随机访问(直接访问):在一组长度为n的数据中,要找到其中的第i个元素,只需要通过下标就能访问到。

就是根据索引就能直接访问到我想访问的元素

其中数组就可以进行随机访问不是嘛?比如,array[i]。

数组在内存中的存储结构是像一个火车一样,一节一节的。

例如java中int的长度是4字节(32位),起始地址0x00000001,即“车头”的开始位置,那么下一节“车厢”的开始位置为0x00000033,

依次类推0x00000065…所以数组中索引为0的数据位置就在0x000000001~0x00000032中。

这样的话,知道了起始地址,和数据长度,就可以实现随机访问。

比如访问array[2],array[2]数据的起始地址:0x00000001 + 32 * 2

好了那下面看看源码

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable

Note that this implementation is not synchronized.

AbstractList

Collection接口

这里面定义了一些对集合内元素的处理方法

在这里插入图片描述

List接口

继承了Collection接口,在Collection定义的方法的基础上,又增加了一些方法。

在这里插入图片描述

AbstractCollection抽象类

1.实现类Collection接口中的方法,即能对数组进行操作了。

但是,返回数组大小和遍历器遍历的方法没有实现。

在这里插入图片描述

AbstractList
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> 

它有两个内部类

这俩内部类是遍历用的。

private class ListItr extends Itr implements ListIterator<E>
private class Itr implements Iterator<E>

还有两个同级的类

class SubList<E> extends AbstractList<E>
class RandomAccessSubList<E> extends SubList<E> implements RandomAccess

SubList 其实就是一个新的AbstractList,返回一个新的被截取的链表用的。官方文档称为视图。

RandomAccessSubList继承了SubList,实现了RandomAccess。而RandomAccess是个空空如也的接口,

里面的注释有这样一句话

marker interface used by List implementations to indicate that they support fast (generally constant time) random access.

所以这个接口就是一个标志,标志着这个类使用索引遍历比迭代器要快。

ArrayList
public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable

终于到了研究ArrayList这一部了

在这里插入图片描述

同样,ArrayList里面也有Ltr , Listltr,SubList三个内部类,其中Ltr是完全一样的,这里算不算代码重复呢?

其中还有ArrayListSpliterator内部类。(TODO)

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
contains()方法

调用了indexOf()方法,根据返回的索引值是否大于等于0,来判断是否存在。

而indexOf()方法是,是通过遍历查询的。

array的排序,是调用了Arrays.sort() ,

Arrays.sort() 对于小数组,用的是插入排序的方法。

对于超过了界定的小数组的长度,用递归排序。

下面是具体源码

private static void mergeSort(Object[] src,
                                  Object[] dest,
                                  int low, int high, int off,
                                  Comparator c) {
        int length = high - low;

        // Insertion sort on smallest arrays
        if (length < INSERTIONSORT_THRESHOLD) {
            for (int i=low; i<high; i++)
                for (int j=i; j>low && c.compare(dest[j-1], dest[j])>0; j--)
                    swap(dest, j, j-1);
            return;
        }

        // Recursively sort halves of dest into src
        int destLow  = low;
        int destHigh = high;
        low  += off;
        high += off;
        int mid = (low + high) >>> 1;
        mergeSort(dest, src, low, mid, -off, c);
        mergeSort(dest, src, mid, high, -off, c);

        // If list is already sorted, just copy from src to dest.  This is an
        // optimization that results in faster sorts for nearly ordered lists.
        if (c.compare(src[mid-1], src[mid]) <= 0) {
           System.arraycopy(src, low, dest, destLow, length);
           return;
        }

        // Merge sorted halves (now in src) into dest
        for(int i = destLow, p = low, q = mid; i < destHigh; i++) {
            if (q >= high || p < mid && c.compare(src[p], src[q]) <= 0)
                dest[i] = src[p++];
            else
                dest[i] = src[q++];
        }
    }

…其他的方法其实点进去看看也就明白了。不想再花时间做了。

这些都不太重要,重要的是ArrayList其实就是维护了个数组。

肝了一天的源代码,突然觉得我人傻了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值