当前位置: 首页 > news >正文

山东做网站建设的好公司哪家好/做一个自己的网站

山东做网站建设的好公司哪家好,做一个自己的网站,tor网站建设,wordpress电话按钮【ArrayList】白话文源码分析ArrayList类解析全局变/常量构造方法无参构造:有参构造(参数为int)有参构造(参数为Collection集合)其他方法add()扩容机制:remove()打好基础,再说其他的&#xff0c…

【ArrayList】白话文源码分析

  • ArrayList类解析
    • 全局变/常量
    • 构造方法
      • 无参构造:
      • 有参构造(参数为int)
      • 有参构造(参数为Collection集合)
    • 其他方法
      • add()
        • 扩容机制:
      • remove()

打好基础,再说其他的,不要整天好高骛远。

希望我的分享能帮到一样迷茫但努力的同学。

ArrayList类解析

首先我想对一些基础不好同学说一句。ArrayList是一个,不是你们认为的就直接操作内存了。
既然ArrayList是一个类,那么类就有类的规则,有规则我们就能学习。我们来看看这个类的结构:

public class ArrayList<E> extends AbstractList<E>implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{1.全局变/常量private static final long serialVersionUID = 8683452581122892189L;private static final int DEFAULT_CAPACITY = 10;private static final Object[] EMPTY_ELEMENTDATA = {};private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};transient Object[] elementData; private int size;
===================================================================================
2. 构造方法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);}}public ArrayList() {this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;}public ArrayList(Collection<? extends E> c) {elementData = c.toArray();if ((size = elementData.length) != 0) {if (elementData.getClass() != Object[].class)elementData = Arrays.copyOf(elementData, size, Object[].class);} else {this.elementData = EMPTY_ELEMENTDATA;}}
===================================================================================
3. 其他方法
。。。。。。。}

整个ArrayList类我们就分为三个模块来解释。

  1. 全局变/常量
  2. 构造方法
  3. 其他方法(继承自父类和接口的具体的集合操作方法,如.add()等)

全局变/常量

ArrayList操作和这些变/常量是息息相关的,我们必须要非常清楚得知道每一个变/常量的含义是什么。

定义默认值含义
serialVersionUID8683452581122892189L可以看到这是一个静态常量,这个常量主要是用于对象序列化时的唯一标识,这里我们不去了解它。
DEFAULT_CAPACITY10可以看到这是一个静态常量,默认为10,此字段用作表示ArrayList集合的初始化长度
EMPTY_ELEMENTDATA{}可以看到这是一个静态常量,用于表示空数组
DEFAULTCAPACITY_EMPTY_ELEMENTDATA{}可以看到这是一个静态常量,用于表示空数组,但和EMPTY_ELEMENTDATA含义不同,DEFAULTCAPACITY_EMPTY_ELEMENTDATA用在初始化集合的时候。
elementData{}这是一个变量,用于表示当前的集合对象增删改查都是操作的它。
size0这是一个变量,用于表示当前集合的长度。

构造方法

要了解上面的变/常量的含义,最好就是通过读代码一行一行得慢慢熟悉。
构造方法就是我们了解一个类的第一步。

我们发现ArrayList有三个构造方法,我们从易到难依次分析一下。

无参构造:

当我们平时写List myList = new ArrayList()的时候就会调用下面的这个无参构造方法创建一个ArrayList对象。
我们看看构造方法做了什么事情:

    public ArrayList() {this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;}
===================================================================================    1.this.elementData。this指的是当前的ArrayList对象,elementData指的是当前对象的数组对象。2.DEFAULTCAPACITY_EMPTY_ELEMENTDATA。指初始化时的空数组常量。3.整个构造方法就是把一个空数组赋值给我们new的ArrayList对象。

因此,调用无参构造创建集合的时候,集合为空,长度为size=0;(int值默认为0)

有参构造(参数为int)

当我们平时写List myList = new ArrayList(5)的时候就会调用下面的这个有参构造方法创建一个ArrayList对象。
我们看看构造方法做了什么事情:

   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);}}
===================================================================================    
1.我们从参数名就知道,这个参数是用来指定集合创建时的集合初始长度的。
2.如果参数>0,初始化并赋值给集合对象一个该参数长度的数组。
3.如果参数=0,赋值给集合对象一个空数组。
4.else,说明参数无效或非法,报错。

因此,我们可以利用这个构造方法在创建集合的时候就指定集合的长度

有参构造(参数为Collection集合)

Collection是List的父类,List是ArrayList的父类。
所以,当我们平时写List myList = new ArrayList(Collection子类集合)的时候就会调用下面的这个有参构造方法创建一个ArrayList对象。
比如我们现在要把一个Set集合赋值给ArrayList集合,就要调用这个构造方法。
我们看看构造方法做了什么事情:

    public ArrayList(Collection<? extends E> c) {elementData = c.toArray();if ((size = elementData.length) != 0) {if (elementData.getClass() != Object[].class)elementData = Arrays.copyOf(elementData, size, Object[].class);} else {this.elementData = EMPTY_ELEMENTDATA;
===================================================================================
1.把Collection集合参数.toArray()转成数组,并赋值给当前集合对象中的elementData变量。
2.把elementData的长度赋值给变量size。
3.如果size!=0,并且如果elementData的类模板对象不是Object[]的类模板对象
4.就强转为Object对象并赋值给elementData (这里主要是防止数组类型不同做的预防)
5.如果size为0,赋值给集合对象一个空数组。

看文章的时候记得反复回去看看全局变/常量那个表格。

其他方法

这里呢,就分析几个最常用的方法,主要是理解,不要死记硬背。

add()

当我们要给集合添加元素的时候会调用这个.add()方法。这也是要了解ArrayList的最重要的一个方法。
我们开始:

    public boolean add(E e) {ensureCapacityInternal(size + 1);  elementData[size++] = e;return true;}
===================================================================================    
1.e就是我们要添加的元素
2.方法进来第一行就去调用了一个ensureCapacityInternal方法,传入了当前size+1最为参数,作为期望最小容量去判断是否需要扩容。
3. ensureCapacityInternal方法调用完成(成功)之后,把元素赋值到数组的最后一位。
4. 返回true,添加完成。

很明显,重点就是在ensureCapacityInternal(方法里面了),我们点过去看看:

    private void ensureCapacityInternal(int minCapacity) {ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));}private static int calculateCapacity(Object[] elementData, int minCapacity) {if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {return Math.max(DEFAULT_CAPACITY, minCapacity);}return minCapacity;}private void ensureExplicitCapacity(int minCapacity) {modCount++;if (minCapacity - elementData.length > 0)grow(minCapacity);}
===================================================================================
1.第一行就是ensureCapacityInternal方法,我们看到这个方法先后调用了calculateCapacity和ensureExplicitCapacity方法。
2.我们先看calculateCapacity方法,两个参数elementData:当前数组对象,长度为10。minCapacity:传过来的size+1,后面统称为最小容量。
3.判断当前数组对象是否为空,如果为空就在默认容量(10)和最小容量选一个最大的返回。
4.如果数组不为空,直接返回最小容量。
5.我们拿到这个int值能干嘛呢。
6.带着这个值来到ensureExplicitCapacity方法,第一步modCount++;我们不管它,主要是记录集合的操作数。如果最小需要空间比elementData的内存空间要大,则需要扩容,来到grow(minCapacity)方法。

因此,我们知道了,集合在添加第一个元素的时候才会初始化一个长度为10的集合。

接下来就是grow()方法了,顾名思义,grow,我们要开始扩容了。

扩容机制:

    private void grow(int minCapacity) {int oldCapacity = elementData.length;int newCapacity = oldCapacity + (oldCapacity >> 1);if (newCapacity - minCapacity < 0)newCapacity = minCapacity;if (newCapacity - MAX_ARRAY_SIZE > 0)newCapacity = hugeCapacity(minCapacity);elementData = Arrays.copyOf(elementData, newCapacity);}
===================================================================================
1. 参数minCapacity是之前我们计算出来当前集合可以接受的最小长度。
2. 先得到原数组的长度   oldCapacity 
3. 再根据算法算出新长度  newCapacity (老长度的1.5倍)
4.  再判断一下新数组的容量够不够,够了就直接使用这个长度创建新数组,不够就将数组长度设置为需要的长度。
5. 检查长度是否超出最大值。
6. 调用Arrays.copyOf方法将elementData数组指向新的内存空间时newCapacity的连续空间并将elementData的数据复制到新的内存空间    

remove()

面试常问,为什么ArrayList对集合中元素的增删效率很低。我们来看看为什么:
下图是更具下标删除元素。假如我们现在有3个元素,我要删除下标是1的元素,底层会怎么做呢?

    public E remove(int index) {rangeCheck(index);modCount++;E oldValue = elementData(index);int numMoved = size - index - 1;if (numMoved > 0)System.arraycopy(elementData, index+1, elementData, index,numMoved);elementData[--size] = null;  // clear to let GC do its workreturn oldValue;}
===================================================================================
1. 第一步,检查传入的下标是否合法。
2. modCount++;操作数+13. 得到要删除的元素的值。
4. numMoved,如果numMoved =0,说明被删除的元素是第一个或最后一个,不需要整体拷贝。numMoved为需要移动的元素个数。
5. 通过判断,System.arraycopy方法是native修饰的,直接操作内存,整个数组下标移动,很慢。
6. 因为删除了一个元素,size需要-1。并把数组最后一个元素置为null,等待GC删除。
7. 返回被删除的值

其他的方法可以自己一步一步去看。

http://www.lbrq.cn/news/1613251.html

相关文章:

  • 有做自由行包车的网站/全网营销代理加盟
  • 开发平台免费版/seo快速培训
  • web编程/seo怎么做优化方案
  • 购物网站的设计思路/网店培训班
  • 网站单页推广/seo技术专员招聘
  • 网页传奇哪个比较好玩/seo网站优化优化排名
  • 做外贸在什么网站最好/seo网络优化公司
  • 建设银行南通通州支行网站/文案写作软件app
  • 株洲的网络营销公司有哪些/seo搜索引擎优化实训总结
  • 汉中专业网站建设推广/带佣金的旅游推广平台有哪些
  • 廊坊seo建站/推广普通话的意义是什么
  • 前端怎么做自己的博客网站/东莞seo优化排名推广
  • 网站制作方案垂直领域获客/店铺推广引流的方法
  • 华强北网站建设/seo检查工具
  • 贵阳网站建设哪家/微信推广图片
  • wordpress 伪娘/班级优化大师怎么加入班级
  • wordpress上传图片/爱站网seo培训
  • 网站开发自我介绍代码/郑州网站建设推广
  • 游戏推广犯法吗/宁波seo如何做推广平台
  • 网站建设宣传语怎么写/国外免费ip地址
  • 空间网站链接怎么做/爱站网查询
  • 新网站如何做seo推广/做一个微信小程序需要多少钱
  • 做网站营销怎么去推广/江苏搜索引擎优化
  • 大连网站建设选网龙/云优化seo软件
  • 汉川市城乡建设局网站/青岛seo招聘
  • 山东泰安特产/优化关键词排名哪家好
  • 北京住房建设委员会官方网站/百度关键词排名代发
  • 宝塔做两个网站6/宁波关键词优化品牌
  • 网站建设系统 招标/品牌宣传活动策划方案
  • 上海网站开发制作公司/seo排名
  • 【Java】在一个前台界面中动态展示多个数据表的字段及数据
  • WD5208S,12V500MA,应用于小家电电源工业控制领域
  • Python 字典为什么查询高效
  • day38 力扣279.完全平方数 力扣322. 零钱兑换 力扣139.单词拆分
  • Rust在CentOS 6上的移植
  • SpringAI智能客服Function Calling兼容性问题解决方案