深度解析ArrayList使用_arrylist-程序员宅基地

技术标签: jvm  JAVA SE  java  前端  数据结构与算法  数据结构  

在这里插入图片描述

一、ArrayList是什么?

ArrayList 类是一个可以动态修改的数组,与普通数组的区别就是它是没有固定大小的限制,我们可以添加或删除元素。ArrayList 继承了 AbstractList ,并实现了 List 接口。
在这里插入图片描述

在这里插入图片描述
我们发现ArrayList类位于java.util包中,使用之前需要去引入它.

import java.util.ArrayList;

ArrayList如何定义:

ArrayList<E> arrayList = new ArrayList<E>();

此数E为泛型实参类型,只能为引用数据类型,ArrayList想存储什么类型的数据,我们就传什么就可以。

List<E> list = new ArrayList<E>();

因我们的ArrayList是继承于List的,所以我们可以用父类去接受子类对象,向上转型。

二、ArrayList的构造方法

在这里插入图片描述
我们发现ArrayList一共提供了三种构造方法。
构造方法1:
构造一个空的顺序表

        List<Integer> list = new ArrayList<>();

构造方法2:
构造一个指定大小为5的顺序表

        List<Integer> list = new ArrayList<>(5);

构造方法3:
在这里插入图片描述
此处传入的要么是自己本身类型,或者是子类类型。
此处构造一个和list2元素一致的顺序表

        List<Integer> list2 = new ArrayList<>(5);
        List<Integer> list = new ArrayList<>(list2);

初始时的坑

List list = new ArrayList();

这样对顺序表进行初始化的话,没有指定任何类型,这样的话可以存放任意类型的元素,这样会存在很大的安全隐患。

三、ArrayList的常见方法

常见方法

在我的上一篇实现顺序表中,已经把大多数方法手动实现了一遍,此处我在说明几个重点的。
在这里插入图片描述
remove方法
ArrayList提供给我们两个remove方法
在这里插入图片描述
一个是传入要删除的下标,一个是要删除的引用。

public static void main(String[] args) {
    
        List<Integer> list = new ArrayList<>();
        list.add(10);
        list.add(8);
        list.remove(1);
        System.out.println(list);
    }

如果我们传入的是int类型那么我们删除的是该下标的数据。
在这里插入图片描述

public static void main(String[] args) {
    
        List<Integer> list = new ArrayList<>();
        list.add(10);
        list.add(8);
        list.remove(new Integer(10));
        System.out.println(list);
    }

如果我们传入的是引用数据类型,那么将删除该顺序表中的该引用数据。
在这里插入图片描述
subList方法

public static void main(String[] args) {
    
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        System.out.println("截取之前的list:"+list);
        List<Integer> list1 = list.subList(1,3);
        list1.set(0,5);
        System.out.println("截取之后的list:"+list);
    }

在这里插入图片描述
为啥改了list1之后,list的数据也发生了变化。
在这里插入图片描述
因为在截取之后并没有复制一份内容给list1,而是指向同一块内容。

遍历ArrayList

方法1:

public static void main(String[] args) {
    
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        for (int i = 0; i < list.size(); i++) {
    
            System.out.print(list.get(i)+" ");
        }
        System.out.println();
    }

方法2:

public static void main(String[] args) {
    
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        for (Integer x:list) {
    
            System.out.print(x+" ");
        }
        System.out.println();
    }

方法3:
使用迭代器
在这里插入图片描述

方法 作用
.next() 返回迭代器写一个元素,更新迭代器状态
.hasNext() 检测集合中是否还有元素
.remove() 将迭代器返回的元素删除
public static void main(String[] args) {
    
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        Iterator<Integer> it = list.listIterator();
        while (it.hasNext()) {
    
            System.out.print(it.next()+" ");
        }
        System.out.println();
    }

使用迭代器删除元素

我们删除集合小于3的元素

public static void main(String[] args) {
    
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        Iterator<Integer> it = list.listIterator();
        while (it.hasNext()) {
    
            if(it.next() < 3) {
    
                it.remove();
            }
        }
        System.out.println(list);
    }

在这里插入图片描述
迭代器的remove方法只能删除当前指向的元素。

四、ArrayList的扩容机制

List<Integer> list = new ArrayList<>();

很多资料都在说这样初始化一个集合,说默认大小为10,那事实到底是不是如此呢?我们一步步查看源码一探究竟。

在这里插入图片描述
我们发现当前引用指向后面那个引用
在这里插入图片描述
我们发现这里的引用是一个空引用,初始集合时,是一个空集合
那如何扩容呢?
既然我们的顺序表是空的,那如何add呢?
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
如果是无参构造的话,就传一个默认大小和传入大小的最大值。
在这里插入图片描述
我们可以发现如果大于数组大小时,就会grow。
在这里插入图片描述
我们可以发现计算一个新容量,和我们传入的大小做比较,如果新容量小于传入的大小时,指定当前集合大小为传入的大小。否则,对集合大小进行1.5倍扩容。
在这里插入图片描述
但如果我们1.5倍扩容的大小超过了这个指定的范围2147483639时
在这里插入图片描述
系统会报一个内存溢出异常。

1. 检测是否真正需要扩容,如果是调用grow准备扩容
2. 预估需要库容的大小
初步预估按照1.5倍大小扩容
如果用户所需大小超过预估1.5倍大小,则按照用户所需大小扩容
真正扩容之前检测是否能扩容成功,防止太大导致扩容失败
3. 使用copyOf进行扩容

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/buhuisuanfa/article/details/126926645

智能推荐

解决Unity开启多个协程卡顿问题_unity 多个协程-程序员宅基地

文章浏览阅读3.1k次。Unity开启多个协程往往造成卡顿,因此需要每完成一个协程再新开启一个协程。for (int i = 0; i < result.result.Count; i++) { try { BaseStation responses = JsonMapper.ToObject<BaseStation>(JsonMapper.ToJson(result.result[i])); ..._unity 多个协程

spring+SpringMvc+Mybaits配置多个数据库_springmvc+mybatis配置多个数据库-程序员宅基地

文章浏览阅读410次。一、配置文件二、创建一个实体类,切换数据库三、切换数据库的代码_springmvc+mybatis配置多个数据库

前端框架们_阿里 前端框架 乌米-程序员宅基地

文章浏览阅读675次。我司打算搞个地图应用,领导发给我一份ppt,里面有个前端的技术架构图:what!前端技术都进化得这么复杂啦?就搞一个前端,至于用到这么多框架?就问你晕不晕!底部的es6,fetch是基础的语法,这个没什么好讲的。arcgis jsapi,是地图服务接口,也没什么好说的。webpack,打包工具,还行吧。顶部的echarts,经常用,很好用,不错。但ant design是蚂蚁金服的东东,与r..._阿里 前端框架 乌米

Turn on ClearType。打开ClearType看英文资料不再那么费眼。-程序员宅基地

文章浏览阅读64次。下面是微软提供的在线打开ClearType 网址,装好插件之后按提示一步一步的点下去。发现还是比较爽的。呵呵~http://www.microsoft.com/typography/cleartype/tuner/Step1.aspx转载于:https://www.cnblogs.com/zwwon/archive/2007/07/10/812598.html..._chrome 英文和数字显示cleartype

jQuery.template.js 简单使用-程序员宅基地

文章浏览阅读125次。之前看了一篇文章《我们为什么要尝试前后端分离》,深有同感,并有了下面的评论:我最近也和前端同事在讨论这个问题,比如有时候前端写好页面给后端了,然后后端把这些页面拆分成很多的 views,有时候还会在这些 view 中写一些 c# 代码,突然有一天前端页面的样式出错了,但前端那里并没有问题,然后后端把前端叫过来,说你在我这里调吧,因为你没有后端的调试环境,然后前端就会很不爽,然后。。。你懂的!..._/template/pc/skin/js/jquery.js

天池:零基础入门NLP - 新闻文本分类_天池学习赛零基础入门nlp - 新闻文本分类完成-程序员宅基地

文章浏览阅读256次。天池:零基础入门NLP - 新闻文本分类赛题理解解题思路赛题理解赛题链接:https://tianchi.aliyun.com/competition/entrance/531810/information划重点:字符级匿名处理(防止人工标注答案)、14个分类类别(0-13)、评价标准为类别f1_score的均值(越大越好)解题思路【难点】数据形式是匿名化字符,无法分词【分析】文本数据是典型的非结构化数据,可能涉及特征提取和分类模型两个部分【思路】TF-IDF + 机器学习分类器_天池学习赛零基础入门nlp - 新闻文本分类完成

随便推点

react Link跳转无效_React Native开发之react-navigation详解-程序员宅基地

文章浏览阅读299次。众所周知,在多页面应用程序中,页面的跳转是通过路由或导航器来实现的。在0.44版本之前,开发者可以直接使用官方提供的Navigator组件来实现页面的跳转,不过从0.44版本开始,Navigator被官方从react native的核心组件库中剥离出来,放到react-native-deprecated-custom-components的模块中。 如果开发者需要继续使用Navigator,则需要..._react navigate(-1) url不生效

python倒计时60,Python微项目分享之重要事件倒计时-程序员宅基地

文章浏览阅读109次。作者:JiawuZhang出品:JiawuLab(ID:jiawulab)微项目系列是JiawuLab原创栏目,每期选取一个自创项目或发现有趣的项目,进行代码、逻辑分析,达到python学习目的。大家好,我是JiawuZhang,本期微项目是——事件倒计时。项目介绍“11月11日0点0分0秒!”你是不是也在等着这个时间?看看电视,玩玩手机,刷刷购物车,只为等着这个时间到来。图片来自网络我老婆也是这..._python倒计时60秒

Could not connect to https://mirrors.tuna.tsinghua.edu.edu.cn/anaconda/pkgs/free/noarch/_could not connect to mirrors.tuna.tsinghua.edu.cn-程序员宅基地

文章浏览阅读5k次。解决方法:删除 .condarc文件 。 .condarc以点开头,一般表示 conda 应用程序的配置文件,在用户的根目录 (windows:C:\users\username\,linux:/home/username/)。但对于.condarc配置文件,是一种可选的(optional)运行期配置文件,其默认情况下是不存在的。 ..._could not connect to mirrors.tuna.tsinghua.edu.cn

MAC安装git的三种方式-程序员宅基地

文章浏览阅读1.7w次,点赞7次,收藏25次。以上是在MAC操作系统中安装Git的三种不同方式。Homebrew是最方便的方式之一,但如果您不想使用Homebrew,则可以选择从官方Git网站下载安装程序或使用Xcode Command Line Tools安装Git。无论您选择哪种方法,都应该能够很容易地安装和使用Git。_mac安装git

基于风控特征相关度,挖掘贷中等场景中的存量客户价值|来看看相关实操_风控 建立存量客户的特征标签-程序员宅基地

文章浏览阅读836次。基于风控特征相关度,挖掘贷中等场景中的存量客户价值|来看看相关实操_风控 建立存量客户的特征标签

Internet Download Manager v6.36 Build 3 Final 注册版-IDM下载工具_ternet_download_manager 注册版-程序员宅基地

文章浏览阅读1.9k次。亲测可用Internet Download Manager(简称IDM)下载速度最多达其他下载工具5倍的下载具。Internet Download Manager的续传功能可以恢复因为断线、网络问题、计算机当机甚至无预警的停电导致下传到一半的软件。此程序具有动态档案分割、多重下载点技术,而且它会重复使用现有的联机,而不需再重新联机登入一遍。聪明的in-speed技术会动态地将所有设定应用到某种..._ternet_download_manager 注册版

推荐文章

热门文章

相关标签