作者:陌北有棵树,玩Java,架构师社区合伙人!

【一】关于扩容

如果没有指定初始容量,则设置为10

/** * Default initial capacity. */private static final int DEFAULT_CAPACITY = 10;

ArrayList的扩容比较简单,容量扩为之前的1.5倍/** * Increases the capacity to ensure that it can hold at least the * number of elements specified by the minimum capacity argument. * * @param minCapacity the desired minimum capacity */private void grow(int minCapacity) {    // overflow-conscious code    int oldCapacity = elementData.length;    int newCapacity = oldCapacity + (oldCapacity >> 1);    if (newCapacity - minCapacity 0)        newCapacity = minCapacity;    if (newCapacity - MAX_ARRAY_SIZE > 0)        newCapacity = hugeCapacity(minCapacity);    // minCapacity is usually close to size, so this is a win:    elementData = Arrays.copyOf(elementData, newCapacity);}

【二】关于拷贝

源码中用到的数组复制的两个方法分别是:System.arraycopy()和Arrays.copyOf()

一句话总结二者区别:Arrays.copyOf()可以看做是受限制的System.arraycopy()

Arrays.copyOf()是系统自己创建一个数组,再调用System.arraycopy()复制

public static  T[] copyOf(U[] original, int newLength, Class extends T[]> newType) {@SuppressWarnings("unchecked")    T[] copy = ((Object)newType == (Object)Object[].class)        ? (T[]) new Object[newLength]        : (T[]) Array.newInstance(newType.getComponentType(), newLength);    System.arraycopy(original, 0, copy, 0,                     Math.min(original.length, newLength));return copy;}

System.arraycopy()需要传入一个目标数组作为参数,同时可以指定拷贝的起点和拷贝的长度

public static native void arraycopy(Object src,  int  srcPos,                                    Object dest, int destPos,int length);

各个参数的含义:

src - 源数组。
srcPos - 源数组中的起始位置。
dest - 目标数组。
destPos - 目标数据中的起始位置。
length - 要复制的数组元素的数量。

同时要注意的是,上述两个拷贝方法都是浅拷贝,关于深拷贝和浅拷贝,后续会做详细说明。

【三】关于Fail-Fast

Fail-Fast是非线程安全的集合,实现的一种错误机制。但不能百分百得到保证,只是尽最大努力抛出ConcurrentModificationException。

什么时候产生Fail-Fast
ArrayList中如何实现Fail-Fast
两个变量:modCount和expectedModCount
只要涉及到数组个数改变的方法,都会导致modCount的改变(add、remove、clear)
当发现expectedModCount和modCount不一致,就会抛出ConcurrentModificationException
所以,Iterator在遍历时,是不允许被迭代的对象被改变的

final void checkForComodification() {    if (modCount != expectedModCount)        throw new ConcurrentModificationException();}

如何避免Fail-Fast:用CopyOnWriteArrayList代替ArrayList

【四】关于ArrayList中删除元素

错误的删除方式一:for循环遍历删除

public void testRemove() {   List integers = new ArrayList<>(5);   integers.add(1);   integers.add(2);   integers.add(2);   integers.add(4);   integers.add(5);for (int i = 0; i       if (integers.get(i) % 2 == 0) {         integers.remove(i);      }   }   System.out.println(integers);}

这段代码的输出是 [1,2,5]

因为在remove方法执行的时候,删除第一个“2”,会更新后面的索引值,数组变为[1,2,4,5],这样会导致第二个“2”不会被删除

错误的删除方式二:使用Iterator遍历,但仍用ArrayList的remove方法

public void testRemove(){   List strings = new ArrayList<>();   strings.add("a");   strings.add("b");   strings.add("c");   strings.add("d");   Iterator iterator = strings.iterator();while (iterator.hasNext()){      String next = iterator.next();      strings.remove(next);   }   System.out.println(strings);}

会抛出ConcurrentModificationException,参见上述的Fail-Fast机制

正确的删除方法:使用Iterator的remove方法

public static void main(String[] args) {   List intList = new ArrayList();   Collections.addAll(intList, 1, 2, 3, 5, 6);   Iterator it = intList.iterator();while(it.hasNext()) {      Integer value = it.next();if(value == 3 || value == 5) {         it.remove();      }   }   System.out.println(intList);}

长按订阅更多精彩▼

如有收获,点个在看,诚挚感谢

arraylist 的扩容机制_每天都用ArrayList,你读过它的源码么?相关推荐

  1. arraylist 的扩容机制_ArrayList详解

    作者丨HUC南枫 来源丨甲哇技术栈(jiawa1024)ArrayList 的底层是数组队列,相当于动态数组.与 Java 中的数组相比,它的容量能动态增长.在添加大量元素前,应用程序可以使用ensu ...

  2. java基础巩固-宇宙第一AiYWM:为了维持生计,多高(多线程与高并发)_Part9~整起(单双列集合们、ArrayList 的扩容机制、HashMap、ConcurrentHashMap )

    再进入正文之前,先看看集合相关操作的时间复杂度: 本故事源自于~ 开唠: PART0: 为什么突然蹦出集合这个玩意,就是因为咱们基础那里学的"数组"不够用~: 数组一般用来保存一组 ...

  3. 各种风格简洁单页响应式html5模板_简洁 响应式 单页 跳转 设计 案例 源码340多套订餐企业模板高大尚响应式网站模板html5网页静态模板Bootstrap扁平化网站源码css3手机seo自适响

    各种风格简洁单页响应式html5模板_简洁 响应式 单页 跳转 设计 案例 源码340多套订餐企业模板高大尚响应式网站模板html5网页静态模板Bootstrap扁平化网站源码css3手机seo自适响 ...

  4. arraylist扩容是创建新数组吗 java_arraylist扩容机制要怎么实现?arraylist怎么扩容...

    ArrayList大家都知道了吧,这是一个动态数组.以java语言来说,数组是定长的,在被创建之后就不能被加长或缩短了,因此,了解它的扩容机制对使用它尤为重要.下面,我们就一起来看看它的扩容机制是怎么 ...

  5. 说一说 ArrayList 的扩容机制

    ArrayList有三种方式来初始化,构造方法源码如下: /*** 默认初始容量大小*/private static final int DEFAULT_CAPACITY = 10;private s ...

  6. ArrayList的扩容机制

    在Java中,ArrayList是一个使用非常频繁的集合类型,它的底层是Object数组,所以它拥有数组所拥有的特性,比如支持随机访问,所以查询效率高,但插入数据需要移动元素,所以效率低. 先来看看若 ...

  7. hashmap扩容机制_图文并茂:HashMap经典详解!

    点击上方 Java后端,选择 设为星标 优质文章,及时送达 代码中的注解多看几遍,其中HashMap的扩容机制是要必懂知识!结合图片一起理解! 什么是 HashMap? HashMap 是基于哈希表的 ...

  8. 送分题,ArrayList 的扩容机制了解吗?

    最近在准备暑期实习嘛,所以面经刷的比较多,前几天看见一位上岸的小伙伴写的面经,他说他在整理回顾知识点的时候(一般都用思维导图吧),会把知识点写成疑问句的形式,而不是陈述句,这样你在看到这句话的时候,会 ...

  9. hashmap扩容机制_图文并茂,HashMap经典详解!

    Java面试笔试面经.Java技术每天学习一点 公众号Java面试 关注我不迷路 作者:feigeswjtu 来源:https://github.com/feigeswjtu/java-basics ...

最新文章

  1. 自动驾驶感知系统盘点
  2. 金融学习纲要与相关知识
  3. 转:canvas--放大镜效果
  4. 高性能JavaScript DOM编程
  5. python: numpy--函数 shape用法
  6. python functools
  7. iOS追踪设备和用户
  8. 在Ubuntu中为root用户启用界面登录
  9. java多线程(线程安全,线程同步)
  10. 易到起死回生的背后,谁在指点江山?
  11. kibana日志收集
  12. 人机大战简史:AI如何在20多年中一次次赶超人类
  13. remote debugger java,VS2015 远程调试:Remote Debugger
  14. 个人信息保护中,APP经常调用的Android类和方法
  15. [CSS]CSS 字体属性
  16. 移动端事件touchstart、touchmove、touchend详解
  17. 花呗接入央行征信系统!会影响贷款吗?
  18. 计算机显卡更新,电脑显卡升级,教您显卡怎么升级
  19. 2012-8-18可樂美文分享《遗留在时…
  20. 设计模式私家笔记——概述:设计模式是银弹吗?

热门文章

  1. 动态通过网络获取json来tabbar图片和文字或其他信息
  2. Linux用find查找指定文件的操作
  3. 用JSON-server模拟REST API(一) 安装运行
  4. 之前接触过的测试的相关工具
  5. 关于Sql语句的心得体会
  6. 用SQL实现记录上下移动的思路
  7. linux的系统移植——【PC-开发板】的环境搭建
  8. VMware下主机与虚拟机剪切板独立,无法直接复制粘贴
  9. MYSQL--浅析索引
  10. python算法实现源码_Python实现七个基本算法