基础知识

数组是具有相同类型的数据的集合,也就是说数组的所有元素的类型都是相同的,在所有的数据结构中,数组算是最常见也是最简单的一种数据结构,我们最常见的也就是一维数组,当然还有二维,三维……,数组需要先声明才能使用,数组的大小一旦确定就不可以在变了。比如我们声明一个长度为10的数组

1int[] array = new int[10];

数组的下标是从0开始的,比如上面数组的第一个元素是array[0],最后一个元素是array[9]。

我们还可以在声明的时候直接对他进行初始化,比如

1int[] array = new int[]{1, 2, 3};

上面我们声明了一个长度为3的数组。

源码分析

操作数组的类我们常见的估计也就是ArrayList了,他对数组的操作非常简单,所有的数据都会存放到这个数组中

1transient Object[] elementData;

我们来看一下他常见的几个方法,首先是get方法

1public E get(int index) {2    if (index >= size)3        throw new IndexOutOfBoundsException(outOfBoundsMsg(index));45    return (E) elementData[index];6}

首先判断是否越界,如果越界直接抛异常,否则就根据他的下标从数组中直接返回,在看一下他的set方法

1public E set(int index, E element) {2    if (index >= size)3        throw new IndexOutOfBoundsException(outOfBoundsMsg(index));45    E oldValue = (E) elementData[index];6    elementData[index] = element;7    return oldValue;8}

和get方法一样,也是先判断是否越界,然后再操作,代码比较简单,我们再来看一个add方法

 1public void add(int index, E element) { 2    if (index > size || index 0) 3        throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); 4 5    ensureCapacityInternal(size + 1);  // Increments modCount!! 6    System.arraycopy(elementData, index, elementData, index + 1, 7                     size - index); 8    elementData[index] = element; 9    size++;10}

这里也是先判断是否越界,然后再判断是否需要扩容,最后在操作,接着我们来看一下ensureCapacityInternal方法

 1private void ensureCapacityInternal(int minCapacity) { 2    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { 3        minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); 4    } 5 6    ensureExplicitCapacity(minCapacity); 7} 8 9private void ensureExplicitCapacity(int minCapacity) {10    modCount++;1112    // overflow-conscious code13    if (minCapacity - elementData.length > 0)14        grow(minCapacity);15}

他的默认初始化大小是10

1private static final int DEFAULT_CAPACITY = 10;

上面代码第13行,如果我们需要的空间大于数组长度的时候,说明数组不够用了,要进行扩容,就会执行下面的grow方法,我们来看一下grow方法的代码

 1private void grow(int minCapacity) { 2    // overflow-conscious code 3    int oldCapacity = elementData.length; 4    int newCapacity = oldCapacity + (oldCapacity >> 1); 5    if (newCapacity - minCapacity 0) 6        newCapacity = minCapacity; 7    if (newCapacity - MAX_ARRAY_SIZE > 0) 8        newCapacity = hugeCapacity(minCapacity); 9    // minCapacity is usually close to size, so this is a win:10    elementData = Arrays.copyOf(elementData, newCapacity);11}

代码也比较简单,扩容的时候在第4行还会增加一半的大小,比如原来数组大小是10,第一次扩容后会是15。在ArrayList中无论使用add还是remove都会使用这样一个方法

1        System.arraycopy(elementData, index+1, elementData, index,2                         numMoved);

这说明对数组的查找是比较方便的,但对数组的增删就没那么方便了,因为数组是一块连续的内存空间,如果在前面增加和删除,都会导致后面元素位置的变动。

ArraList是线程不安全,如果使用线程安全的可以用Vector,还有一个线程安全的类

CopyOnWriteArrayList,他只在add和remove的时候,也就是修改数据的时候会先synchronized,在get的时候没有,我们来看一下代码

1private E get(Object[] a, int index) {2    return (E) a[index];3}

我们再来看一下他的add方法

 1public boolean add(E e) { 2    synchronized (lock) { 3        Object[] elements = getArray(); 4        int len = elements.length; 5        Object[] newElements = Arrays.copyOf(elements, len + 1); 6        newElements[len] = e; 7        setArray(newElements); 8        return true; 9    }10}

他不像ArrayList每次扩容的时候,size都会增加一半,他是每次add一个元素的时候size只会加1,同理remove的时候size只会减1。

后话

常见的数据结构种类也不是很多,比如,数组,链表,队列,栈,树,图,等,还有数组和链表结合的,比如HashMap。但每一种又会有很多的分类,比如链表有单向的,双向的,环形的,队列又有一般的队列和双端队列,树又分为二叉树,AVL树,红黑树,B+树,2-3树,哈夫曼树,字典树等等。如果细分下去,还是比较多的,今天讲的数组是最简单的一种数据结构,基本上也没什么可说的,剩下的那些数据结构后续都会一一分析。

扩容是元素还是数组_348,数据结构1,数组相关推荐

  1. 细说PHP笔记03(第7章)--数组与数据结构,数组定义,数组遍历,数组内部指针遍历,键值操作函数,统计数组函数,回调函数处理数组元素,数组排序,拆分、合并、分解、结合数组,数组实现堆栈,随机选取元素

    1.数组 索引数组:索引值是整数 关联数组:索引值是字符串 2.数组的定义 1.以直接赋值的方式声明 $数组名[下标]=资料内容 或 $数组名[关联字符串(键值)]=资料内容 <?php $va ...

  2. Java数组与容器类分析资料--数组、List和Set、Map等

    2019独角兽企业重金招聘Python工程师标准>>> Java容器分析--数组 数组是Java语言内置的类型,除此之外,Java有多种保存对象引用的方式.Java类库提供了一套相当 ...

  3. hashmap 扩容是元素还是数组_HashMap的扩容机制---resize()

    面试的时候闻到了Hashmap的扩容机制,之前只看到了Hasmap的实现机制,补一下基础知识,讲的非常好 原文链接: Hashmap是一种非常常用的.应用广泛的数据类型,最近研究到相关的内容,就正好复 ...

  4. 扩容是元素还是数组_02 数组(附ArrayList源码分析)

    定义 用一组连续的内存空间存储一组具有相同类型的数据的线性表数据结构. 优势 支持通过下标快速的随机访问数据,时间复杂度为O(1). 劣势 通常情况下,插入和删除效率低下,每次操作后,需要进行后续元素 ...

  5. 扩容是元素还是数组_数组是如何随机访问元素?数组下标为什么从0开始,而不是1?...

    作者:鹏磊 来源:搜云库技术团队 数组如何实现随机访问元素 什么是数组? 数组(Array)是一种线性表数据结构,它用一组连续的内存空间,来存储相同类型的数据. 什么是线性表(Linear List) ...

  6. hashmap 扩容是元素还是数组_HashMap 中的容量与扩容实现

    总有人心里有火炬,而且彼此能看见. 高手过招,招招致命 JDK1.8 中 HashMap 的底层实现,我相信大家都能说上来个 一二,底层数据结构 数组 + 链表(或红黑树) ,源码如下/** * 数组 ...

  7. 扩容是元素还是数组_Java中对数组的操作

    数组对于每一门编程语言来说都是重要的数据结构之一,当然不同语言对于数组的实现及处理也不尽相同. Java语言中提供的数组是用来存储固定大小的同类型元素.如:声明一个数组变量,numbers[100]来 ...

  8. 数组合并假设有 n 个长度为 k 的已排好序(升序)的数组,请设计数据结构和算法,将这 n 个数组合并到一个数组,且各元素按升序排列。即实现函数-C-icoding-排序-数据结构

    数组合并 假设有 n 个长度为 k 的已排好序(升序)的数组,请设计数据结构和算法, 将这 n 个数组合并到一个数组,且各元素按升序排列.即实现函数: void merge_arrays(const ...

  9. 扩容是元素还是数组_Map扩容源码

    首先我们运行一段代码: 此时运行,程序正常,接下来我们将注释放开: 此时运行发现,OOM了: 为什么new出来HashMap的时候并没有报OOM,而是在第一次进行put操作的时候才报的OOM?我们来看 ...

  10. hashmap 扩容是元素还是数组_曹工说JDK源码(1)--ConcurrentHashMap,扩容前大家同在一个哈希桶,为啥扩容后,你去新数组的高位,我只能去低位?...

    如何计算,一对key/value应该放在哪个哈希桶 大家都知道,hashmap底层是数组+链表(不讨论红黑树的情况),其中,这个数组,我们一般叫做哈希桶,大家如果去看jdk的源码,会发现里面有一些变量 ...

最新文章

  1. 推荐三款scrum看板协作工具
  2. 【源代码】基于Android和蓝牙的单片机温度採集系统
  3. python爬虫完整实例-Python爬虫 实例
  4. asp.net DataGrid GridView 表格之选中行与获取选中行数据
  5. Xml+Xslt测试工具
  6. java赋值语句_java并发编程之原子性问题
  7. MFC开发IM-第二十一篇、Unicode转成Utf8
  8. 快速排序查询第k个数
  9. Bootstrap 模态框(Modal)插件
  10. oracle job 与存储过程,讲解Oracle中JOB与存储过程的接合用法
  11. (已更新)漫画小程序更新修复接口,自动采集资源,漫画源码漫画小程序源码简单即可发布
  12. 使用mouse without borders无界键盘鼠标工具实现一套键盘鼠标控制两台电脑(非常的奈斯)
  13. 欠缺的_习惯累积沉淀_新浪博客
  14. 大数据学习之环境构建
  15. pythonembed版是什么意思_HTML中embed什么意思?有哪些作用?(附代码)
  16. 关于加强网络舆情监测的几点建议,TOOM强化舆情监控有方法
  17. sqlmap安装配置教程
  18. scp或者ssh报错“no matching host key type found. Their offer: ssh-rsa,ssh-dss“
  19. [前端bug词典]Already included file name ‘文件路径‘
  20. 任鸟飞FPS类型游戏绘制和游戏安全,反外挂研究(二)

热门文章

  1. iOS之深入解析Block的底层原理
  2. 【数据结构与算法】之深入解析“字符串转换整数 (atoi)”的求解思路和算法示例
  3. iOS之深入解析内存管理的引用计数retainCount的底层原理
  4. 下列说法正确的是( )
  5. Python数据类型判断常遇到的坑
  6. 中国大学MOOC 计算机组成原理第4章 测试(中)
  7. 中国大学MOOC 计算机组成原理第4章 测试(上)
  8. 10.2.1 CSS介绍与引入
  9. 2014年第五届蓝桥杯 - 省赛 - C/C++大学A组 - G. 蚂蚁感冒
  10. 征战蓝桥 —— 2013年第四届 —— C/C++A组第5题——前缀判断