2020-10-20        longzqa@163.com        stronglzq

【摘要】针对数组容量固定无法扩展的问题,引入数组列表(ArrayList)。主要对数组列表的声明及基本操作等内容进行介绍,基本操作包括增加元素、插入元素、删除元素以及元素的访问与修改。

  • 为什么要引入数组列表(ArrayList)
  • 数组列表容量为什么能变动
  • 如何声明数组列表
  • 数组列表的增加、插入、删除、修改、访问操作
  • 数组列表的缺陷
  • 如何灵活的扩展数组,又能方便的访问元素
  • 如何降低数组列表的内存消耗 -- 预设列表容量

为什么要引入数组列表(ArrayList)

数组在创建后容量固定,而实际解决问题的过程中,元素的数量是变动的,此时采用数组来存储数据难以满足业务需求,因此引入数组列表。

数组列表容量为什么能变动

在创建数组时,需确定数组长度,此时数组中产生一个个“萝卜坑”(有初始值,若为int类元素,初始值为0),增加元素即为往“萝卜坑”中放入“萝卜”;数组列表可在声明时预估容量,或不预估容量,当不预估容量,或者元素超过预估容量时,若增加一个元素,则会自动申请一个新的数组,将原先数组列表的内容复制到新数组中,并在末端放入新元素。

如何声明数组列表

数组列表是具有类型参数(type parameter)的泛型类(genetic class),故需要在声明数组列表时,指明元素类型,语法为ArrayList<element type>。数组列表的声明语法有三种:

  • ArrayList<element type> name = new ArrayList<element type>();
  • ArrayList<element type> name = new ArrayList<>();,相对于第一种声明方法,省略了等号右侧数组列表的元素类型;
  • var name = new ArrayList<element type>();使用var则一定不能省略等号右侧数组列表的元素类型。
public class Person{
private String name;
private int age; public Person(String name, int age){
this.name = name;
this.age = age;
}
} public class ArrayListTest{
// 用数组列表来存储Person数据
var person = new ArrayList<Person>();
// ArrayList<Person> person = new ArrayList<Person>();
// ArrayList<Person> person = new ArrayList<>();
person.add(new Person("Peter", 20));
person.add(new Person("Tom", 23));
person.add(new Person("Lucy", 26));
}

数组列表的增加、插入、删除、修改、访问

(1)数组列表的增加为在列表末端增加元素,使用add()方法;(2)对位置i的元素修改为e,语句为set(i, e);(3)访问位置i的元素,语句为get(i);(4)在位置i,插入元素e,则原先位置i及之后的元素均向后移一位,语句为add(i, e);(5)删除位置i的元素,语句为remove(i)

注:数组列表的插入、删除效率低。

public ArrayListTest{
// 用数组列表来存储Person数据
var person = new ArrayList<Person>();
// ArrayList<Person> person = new ArrayList<Person>();
// ArrayList<Person> person = new ArrayList<>();
person.add(new Person("Peter", 20));
person.add(new Person("Tom", 23));
person.add(new Person("Lucy", 26)); // 修改元素
person.set(1, new Person("Peter Long", 25));
// 插入元素
person.add(2, new Person("Jack", 30));
// 删除元素
person.remove(0);
// 访问元素
person.get(1);
}

数组列表的缺陷

使用数组列表存在两个缺陷,(1)无法直接通过元素下标来访问元素,不方便;(2)数组列表由于每变动一个元素,均需要重新申请一个新的数组来存放,对内存消耗大;(3)数组列表元素的插入、删除效率低,解决方案为采用链表的数据类型;

如何既灵活的扩展数组,又能方便的访问数组元素?

数组无法灵活的扩展,故引入了数组列表,但数组列表元素访问繁琐,针对各自的问题,有一解决方法:(1)创建一个数组列表,并填充元素;(2)创建一个数组,数组大小为数组列表实际元素的数量;(3)使用toArray方法,将数组列表的元素复制到该数组中。

public class ArrayListTest{
// 用数组列表来存储Person数据
var person = new ArrayList<Person>();
// ArrayList<Person> person = new ArrayList<Person>();
// ArrayList<Person> person = new ArrayList<>();
person.add(new Person("Peter", 20));
person.add(new Person("Tom", 23));
person.add(new Person("Lucy", 26)); // 创建一个数组,大小为数组列表的大小
Person[] personArray = new Person[person.size()];
// 将数组列表的元素复制到数组中
person.toArray(personArray);
}

注:数组列表的size()方法返回数组列表实际元素的数量,而数组的size()方法返回数组容量。

如何降低数组列表的内存消耗?-- 预设列表容量

针对数组列表内存消耗大的问题,可以预设一个列表容量,在元素数量不超过预设容量时,元素的增加不需要重新分配空间。预设列表容量有两种方式:(1)在构造数组列表时,确定列表容量;(2)使用数组列表的ensureCapcity()方法。

public class ArrayListTest{
// 预设数组列表的容量为100
var person = new ArrayList<Person>(100);
// 或 var person = new ArrayList<Person>(); person.ensureCapcity(100);
}

数组列表(ArrayList)的更多相关文章

  1. Java基础(七)泛型数组列表ArrayList与枚举类Enum

    一.泛型数组列表ArrayList 1.在Java中,ArrayList类可以解决运行时动态更改数组的问题.ArrayList使用起来有点像数组,但是在添加或删除元素时,具有自动调节数组容量的功能,而 ...

  2. 泛型数组列表 ArrayList

    为什么使用泛型数组列表而不使用普通数组? 1.普通数组经常会发生容量太大以致浪费的情况 2.普通数组无法动态更改数组 基本概念: 1.采用[类型参数]的[类]---->[泛型类] 2.[泛型类型 ...

  3. 变长数组列表ArrayList

    简介:此数据结构定义为一个ArrayList结构体类型,维护了一个内部堆数组.通过realloc函数实现了数组容量自动扩充,每次扩充到原来的2倍. 通过函数指针实现了使用者根据自己的需求按条件按查找目 ...

  4. 「JavaSE 重新出发」05.02 泛型数组列表、包装类

    泛型数组列表 ArrayList 是一个采用类型参数(type parameter)的泛型类(generic class). java ArrayList<Employee> staff ...

  5. ArrayList数组列表

    ArrayList数组列表 Collection接口和List接口的区别 List接口扩充了Collection接口,添加了索引相关的方法. code example Object get(int i ...

  6. C#.NET中数组、ArrayList和List三者的区别

    数组在C#.NET中是最早出现的,在内存中是顺序连续存储的,所以它的索引速度非常快,赋值与修改元素也很简单:但是,也正因为数组是顺序连续存储的,在两个数据间插入数据是很不方便的,而且在声明数组的时候必 ...

  7. C#中数组、ArrayList和List三者的区别

    在C#中数组,ArrayList,List都能够存储一组对象,那么这三者到底有什么样的区别呢. 数组 数组在C#中最早出现的.在内存中是连续存储的,所以它的索引速度非常快,而且赋值与修改元素也很简单. ...

  8. 在Java中怎样把数组转换为ArrayList?

    翻译自:How to Convert Array to ArrayList in Java? 本文分析了Stack Overflow上最热门的的一个问题的答案,提问者获得了很多声望点,使得他得到了在S ...

  9. 数组、ArrayList、List、LinkedList的区别

    一.数组 数组在内存中是连续存储的,所以它的索引速度非常快,而且赋值与修改元素也很简单. 1.一维数组 声明一个数组: ]; 初始化一个数组: ] { , , , , }; //定长 声明并初始化: ...

随机推荐

  1. 令人困惑的strtotime

    经常会有人被strtotime结合-1 month, +1 month, next month的时候搞得很困惑, 然后就会觉得这个函数有点不那么靠谱, 动不动就出问题. 用的时候就会很慌… 这不, 刚 ...

  2. [LeetCode] 46. 全排列(回溯)

    ###题目 给定一个没有重复数字的序列,返回其所有可能的全排列. 示例: 输入: [1,2,3] 输出: [ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], ...

  3. 宝塔linux部署node项目

    1.安装宝塔linux之后,按需配置,我的是nginx,不是apq的. 2.下载pm2管理器 3.添加站点,将node项目从localhost打包到到站点,node_modules这个无需打包,这个依 ...

  4. shell变量操作${}详细用法

    ${}基本功能 一般情况下$var与${var}是没有区别的,但是用${ }会比较精确的界定变量名称的范围 [root@localhost ~]# A=Linux [root@localhost ~] ...

  5. Linux下日志文件过大解决方案

    很多Linux服务器里的应用程序都是无间断的输出日志,这对于服务器的硬盘是一个很大的考验.良许之前也分享过一篇文章,介绍如何让应用程序在后台执行: linux后台执行命令:&与nohup的用法 ...

  6. springboot之logback配置

    参考了https://blog.csdn.net/hxtxgfzs/article/details/79488163 Spring Boot默认情况下,当使用"Starters" ...

  7. 分布式服务(RPC)+分布式消息队列(MQ)面试题精选

    ​ 分布式系统(distributed system)是建立在网络之上的软件系统.正是因为软件的特性,所以分布式系统具有高度的内聚性和透明性.因此,网络和分布式系统之间的区别更多的在于高层软件(特别是 ...

  8. PYG5.4第十六期第一轮基础六题

    1. HYWZ-dts音效大师破解https://www.chinapyg.com/thread-135090-1-1.html(出处: 飘云阁(PYG官方论坛) ) 2. HYWZ-LopeEdit ...

  9. 干货满满!关于Pycharm远程开发

    可以在Windows中使用Pycharm编写代码,而代码的调试运行可以使用远程服务器中的python解释器. 在本地创建好工程项目(或从git上clone下代码)后,用Pycharm打开: 打开「To ...

  10. 016 01 Android 零基础入门 01 Java基础语法 02 Java常量与变量 10 布尔类型和字符串的字面值

    016 01 Android 零基础入门 01 Java基础语法 02 Java常量与变量 10 布尔类型和字符串的字面值 本文知识点:字面值 关于字面值的概念,需要注意:很多地方,我们可能就把字面值 ...