二、数组列表 —— ArrayList

  

  1、构造方法

  ArrayList 是 Java 中的动态数组,底层实现就是对象数组,只不过数组的容量会根据情况来改变。

  它有个带 int 类型参数的构造方法,根据传入的参数,扩展初始化的数组容量,这个方法是推荐使用的,因为如果预先知道数组的容量,可以设置好初始值,而不用等每次容量不够而扩容,减少 Arrays.copyOf 的次数:

  

  它的很多方法的实现都是依靠 Arrays 这个工具类完成的,足以体现它与数组之间的密切关系。

  比如有个带 Collection 类型的构造方法,实现如下:

  

  2、常用方法

  1)  trimToSize 方法

  Trims the capacity of this ArrayList instance to be the list's current size.

  An application can use this operation to minimize the storage of an ArrayList instance.

  该方法可以去掉 ArrayList 占用的多余的空间或内存,因为 ArrayList 每次扩容后总会有所剩余,如果数组很大,占用的多余的空间会比较大,内存不够时可以使用此方法。

  2)ensureCapacity 方法

  public void ensureCapacity(int minCapacity)

  Increases the capacity of this ArrayList instance, if necessary, to ensure that it can hold at least the number of elements specified by the minimum capacity argument.

  除了在初始化 ArrayList 的时候可以事先定义一个给定的容量之外,还可以用此方法提高 ArrayList 的初始化速度。看下面的例子:

 public static void main(String[] args) {
         int n = 100000;
         String str = "hello google";

         // 没有调用 ensureCapacity() 方法初始化 ArrayList 对象
         ArrayList<String> list = new ArrayList<>();
         long startTime = System.currentTimeMillis();
         for (int i = 0; i <= n; i++) {
             list.add(str);
         }
         long endTime = System.currentTimeMillis();
         System.out.println("time: " + (endTime - startTime) + " ms");

         // 调用 ensureCapacity() 方法初始化 ArrayList 对象
         list = new ArrayList<>();
         startTime = System.currentTimeMillis();
         list.ensureCapacity(n);
         for (int i = 0; i < n; i++) {
             list.add(str);
         }
         endTime = System.currentTimeMillis();
         System.out.println("time: " + (endTime - startTime) + " ms");
     }

  结果为:

  

  3)isEmpty 方法

  注意此方法是判断是否为空,不是是否为 null

public boolean isEmpty() {
  return size == 0;
}

  4)indexOf 、lastIndexOf 和 contain 方法

  indexOf 方法返回 list 中首次出现给定对象的索引值(从 0 开始),如果不存在则返回 -1。

  lastIndexOf 方法返回 list 中最后一次出现给定对象的索引值(从 size - 1 开始),如果不存在则返回 -1。

  contain 方法 参数为 Object o,判断 list 中是否包含给定的对象,存在则返回 true,源码如下:

  

  5)add,get 和 set 方法

  三个很简单的方法,区别在于:add 方法是数组长度 +1,将给定对象放在最后的位置,set 方法是替换指定索引位置的元素,get 方法则是获取指定索引位置的元素。

  6)remove 方法

  删除指定索引位置的元素或者指定元素,不推荐使用,对数组操作比较复杂,如果你使用了此方法,说明你应该考虑用 LinkedList 了。

  3、最佳使用建议

  1)ArrayList 是 Array 的复杂版本

  ArrayList 内部封装了一个 Object 类型的数组,从一般的意义来说,它和数组没有本质的差别,甚至于 ArrayList 的许多方法,如 Index、IndexOf、Contains、Sort 等都是在内部数组的基础上直接调用 Array 的对应方法。

  2)内部的 Object 类型的影响

  对于一般引用类型来说,这部分的影响不大,但是对于值类型,往 ArrayList 里面添加和修改元素,都会引起装箱和拆箱操作,频繁的操作可能会影响一部分效率。

  3)数组扩容

  这是对 ArrayList 效率影响比较大的一个因素。

  每当执行 Add、AddRange、Insert、InsertRange 等添加元素的方法,都会检查内部数组的容量是否不够了,如果是,它就会以当前容量的两倍来重新构建一个数组,将旧元素 Copy 到新数组中,然后丢弃旧数组,在这个临界点的扩容操作,应该来说是比较影响效率的。 
  例 1:比如,一个可能有 200 个元素的数据动态添加到一个以默认 16 个元素大小创建的 ArrayList 中,将会经过: 
  16*2*2*2*2 = 256 
  四次的扩容才会满足最终的要求,那么如果一开始就以 ArrayList list = new ArrayList(210) 的方式创建 ArrayList,不仅会减少 4 次数组创建和 Copy 的操作,还会减少内存使用。

  例 2:预计有 30 个元素而创建了一个 ArrayList: 
  ArrayList List = new ArrayList(30); 
  在执行过程中,加入了 31 个元素,那么数组会扩充到 60 个元素的大小,而这时候不会有新的元素再增加进来,而且有没有调用 TrimSize 方法,那么就有 1 次扩容的操作,并且浪费了 29 个元素大小的空间。如果这时候,用 ArrayList list = new ArrayList(40) 那么一切都解决了。 
  所以说,正确的预估可能的元素,并且在适当的时候调用 TrimSize 方法是提高 ArrayList 使用效率的重要途径。

特别感谢:

1、Java 中 ArrayList 类的用法

2、《Thinking In Java》

3、《Core Java Volume I》

Java 集合框架(二)—— ArrayList的更多相关文章

  1. Java集合框架之ArrayList浅析

    Java集合框架之ArrayList浅析 一.ArrayList综述: 位于java.util包下的ArrayList是java集合框架的重要成员,它就是传说中的动态数组,用MSDN中的说法,就是Ar ...

  2. (Set, Map, Collections工具类)JAVA集合框架二

    Java集合框架部分细节总结二 Set 实现类:HashSet,TreeSet HashSet 基于HashCode计算元素存放位置,当计算得出哈希码相同时,会调用equals判断是否相同,相同则拒绝 ...

  3. java 集合框架(二)Iterable接口

    Iterable接口是java 集合框架的顶级接口,实现此接口使集合对象可以通过迭代器遍历自身元素,我们可以看下它的成员方法 修饰符和返回值 方法名 描述 Iterator<T> iter ...

  4. Java——集合框架之ArrayList,LinkedList,迭代器Iterator

    概述--集合框架 Java语言的设计者对常用的数据结构和算法做了一些规范(接口)和实现(具体实现接口的类).所有抽象出来的数据结构和操作(算法)统称为Java集合框架(Java Collection ...

  5. Java集合框架(二)

    Set Set:无序,不可以重复元素. |--------HashSet:数据结构是哈希表. 线程是非同步的.保证元素唯一性的原理是:判断元素的hashCode值是否相同,如果相同,还会继续判断元素的 ...

  6. java集合框架03——ArrayList和源码分析

    最近忙着替公司招人好久没写了,荒废了不好意思. 上一章学习了Collection的架构,并阅读了部分源码,这一章开始,我们将对Collection的具体实现进行详细学习.首先学习List.而Array ...

  7. Java集合框架(一)-ArrayList

    大佬理解->Java集合之ArrayList 1.ArrayList的特点 存放的元素有序 元素不唯一(可以重复) 随机访问快 插入删除元素慢 非线程安全 2.底层实现 底层初始化,使用一个Ob ...

  8. java集合框架05——ArrayList和LinkedList的区别

    前面已经学习完了List部分的源码,主要是ArrayList和LinkedList两部分内容,这一节主要总结下List部分的内容. List概括 先来回顾一下List在Collection中的的框架图 ...

  9. 深入理解java集合框架之---------Arraylist集合 -----添加方法

    Arraylist集合 -----添加方法 1.add(E e) 向集合中添加元素 /** * 检查数组容量是否够用 * @param minCapacity */ public void ensur ...

  10. java集合框架之ArrayList

    参考http://how2j.cn/k/collection/collection-arraylist/363.html 使用数组的局限性 一个长度是10的数据:Hero[] heroArr=new ...

随机推荐

  1. [转载]HTML5游戏前端开发秘籍

    http://isux.tencent.com/html5-game-development-cheats.html 转载至腾讯ISUX HTML5游戏前端开发秘籍 本文由米随随编写 QQ空间Andr ...

  2. 【转】C#发送Email邮件

    转自:http://hi.baidu.com/bluesky_cn/item/8bb060ace834c53f020a4df2 下面用到的邮件账号和密码都不是真实的,需要测试就换成自己的邮件账号. 需 ...

  3. TFS 如何強制撤銷被簽出的文件

    我们在使用TFS (Team Foundation Server) 源代码管理的时候,源代码管理会在每个PC上创建一个工作区,然后这个工作区域映像到服务器上的源码文件夹,我们在正常签入,签出的时候,我 ...

  4. Dalsa线扫相机SDK开发-小试牛刀(1)

    拿到了dalsa相机,可以用Sapera软件配置相机,进行图像采集.但是自己开发的话就得撸起袖子写代码了,查了两篇不错的博文,作为指导. Sapera帮助文档 - <好好先生>专栏 - 博 ...

  5. 常用到的一些js方法,记录一下

    获取字符串长度 function GetStringLength(str) { return str.replace(/[^\x00-\xff]/g, "00").length; ...

  6. .net推送微信消息模板

    1.获取access_token public string GetAccess_Token() { string appid = WxPayConfig.APPID; string appsecre ...

  7. 记录.NET Core通过Docker部署到Linux

    1.现在CentOS安装Docker环境(参考地址:https://docs.docker-cn.com/engine/installation/linux/docker-ce/centos/) 我这 ...

  8. NetCore入门篇:(二)Net Core项目创建

    一.新建项目 1.选择菜单:文件 -> 新建 -> 项目 2.选择模板:NET Core -> ASP.NET Core Web 应用程序,输入名称 3.选择框架:ASP.NET C ...

  9. BitAdminCore框架应用篇:(五)核心套件querySuite列的定义

    索引 NET Core应用框架之BitAdminCore框架应用篇系列 框架演示:http://bit.bitdao.cn 框架源码:https://github.com/chenyinxin/coo ...

  10. error while loading shared libraries: libudev.so.0 的问题

    在linux下运行koala的时候遇到了问题: 应该是缺少文件libudev.so.0 在/lib和/lib64目录下也都没有这个文件.然后网上找解决方案,在/lib/x86_64-linux-gnu ...