e安教育 2016-10-26 13:58

【干货】用大白话聊聊JavaSE — ArrayList 深入剖析和Java基础知识详解(一)

对Java程序开发而言,ArrayList 的使用频率是非常高的,尤其在进行 JavaWeb 开发的时候,ArrayList 和 HashMap 这两个类,相信你一定不会陌生,因为天天都在用嘛。

本系列对 ArrayList 做一个解析,同时把Java基础知识个串连进去。一开始我会对如何使用 ArrayList 做一个简要的说明,然后,我们来仿照 ArrayList 封装一个自己的集合框架MyList,通过练习,来一步一步猜想ArrayList 可能的实现方式。

最后,深入到ArrayList 的源码进行解读。

为什么要学习源码?

很简单,一个知道源码的人和一个不知道源码的人,虽然都能使用 ArrayList ,但是,他们在使用的时候,心态是完全不一样的。

只有当你深入了源码,然后你才会对它的一些细节有更充分的认识。这是一本万利的事情。

当然,对于初学者,还是尽量以使用为主,因为源码的话,毕竟有一定的难度。如果一味地追求这些东西,可能会大大降低自己的学习兴趣和热情。

1、 ArrayList 概述

副本难度:一颗星

经验值:500

首先来看一下文档,

All Implemented Interfaces:

Serializable, Cloneable, Iterable<E>, Collection<E>, List<E>, RandomAccess

从图中可以看到,ArrayList 实现了Iterable接口,这个接口表示一种迭代的能力。

既然是ArrayList,那么肯定和 List 有关,所以它果然继承了List接口。

接口的知识点在这里就用上了。

其他接口我们暂且不谈,先继续。

然后,我们看一下官方对ArrayList 做出的说明。

文档中有这么一句:

Resizable-array implementation of the List interface.

这句话是说,ArrayList 是对List接口的一个实现,实现方式是利用一个可改变尺寸的数组,也就是说,它的底层就是一个数组。而且是可改变尺寸的数组,说明这个数组是动态的。

哦,难怪它叫ArrayList ,Array就是数组的意思,那么它肯定和数组有关。

Implements all optional list operations, and permits all elements, including null.

ArrayList 实现了list接口的所有方法,并且允许空元素。

前半句是肯定的,因为在Java中,如果一个类实现了一个接口,那么就必须要重写该接口里所有的抽象方法。

我们知道,接口里只有方法的声明,没有方法的实现。

我对接口的理解,总结以后就只有一句话:

Java类实现接口,就是给这个类本身添加了一个新的身份。

ArrayList是一个类,那么它的身份就是ArrayList,你问他“你叫什么名字呀?”,他肯定会毫不犹豫地告诉你,“我叫ArrayList!”。

白天,我们大家都以为它是ArrayList,结果到了夜晚。

ArrayList竟然摇身一变,成为了Iterable!

原来,ArrayList实现了Iterable,所以它也就拥有了Iterable的身份。

接口其实就是这个意思。网上对接口的解释众说纷纭,反正我总结下来就是这么一句话,也不想搞那么复杂了。

ArrayList不仅有Iterable的身份,还拥有其他好几种身份,比如List,Collection等。

这个情况也叫作多态。

新建一个测试类。

现在我新建一个ArrayList类的实例

这肯定是没问题的。

文档上说,ArrayList 实现了Iterable接口,那么也就是说,它的另一个身份是Iterable。

所以,我这样写是不是也没有问题啊。

就好像白天是普通的上班族,一旦到了夜晚,就。。。

总之,

Iterable iterable = new ArrayList();

这句话的含义就是说,它原来是普通的ArrayList,一旦情况需要,就变身成为Iterable。

好了,既然变成了 Iterable ,那么它是不是也就拥有了 Iterable 的能力?

我们来看一下 Iterable 有哪些方法?

去除继承自Object类的方法不谈,Iterable 只有一个方法,就是 iterator()

它返回的是一个 Iterator ,这是一个迭代器。

通过这个迭代器,我们是不是就可以遍历 ArrayList 中所有的数据了呀?

首先,我们需要一个迭代对象:

当然,这个例子中,ArrayList里面没有数据。

现在思考一个问题,是不是我非得把 ArrayList 对象改变成 Iterable 身份,才可以调用 iterator() 方法呢?

当然不是了,ArrayList 有一个身份是 Iterable ,所以它具有 Iterable 的所有能力(方法),这没问题。那么难道 ArrayList 不变身,就没有 Iterable 的能力了吗?

答案自然是否定的。

一个小说家如果有一天转行去写代码了,那么你觉得他还会不会写小说呢?

肯定会嘛,这没有什么好怀疑的。

所以,代码这么写是不是也没关系?

循环输出

总结一下,ArrayList 它只要实现 Iterable 接口,那么它就必须要拥有 Iterable 规定的所有能力,也就是方法。而接口中,我们知道它里面只有方法的声明,没有方法的实现,所以 ArrayList 需要实现这些方法,实现接口就是这么个意思。

2、 ArrayList常用方法

副本难度:三颗星

经验值:800

2.1、 属性和方法的调用问题

在调用ArrayList的方法之前,我们需要先获得一下ArrayList的实例对象,除了静态方法,其他所有的方法,都只能由对象来调用。

ArrayList是一个类,我更愿意把它称为一个数据模板。它只是一个模板而已,不是一个实实在在的对象,这一点首先要确定。

就好像工厂生产一个产品,首先是不是要有一个模板和设计图纸,这个模板决定了你这个产品是一种怎样的形状,以及可能会具备哪些功能?图纸则决定了功能的具体实现。

比如生成一部手机,模板开出来就是一个扁平的长方体的样子,可是光有模板还不行,你还得规定它的一些具体细节。

这些细节就好比是Java类的构造方法,以及其他的一些方法实现。

但是,你光给客户模板和图纸行吗?

一般来说是不行的。

至于静态方法,我们知道,我们调用静态方法的时候,不需要先生成一个实例,可以通过类名直接调用。

这就相当于,在弄模版的时候,这些功能就已经定制在里面了。

你买手机的时候,里面不是经常有一些内置的应用吗?有些删都删不掉,这不就相当于静态方法吗?

(我只是举一个例子啊,你不要非得较真说我可以ROOT一下啊)

如果模板里面已经有了一些做好的功能,今后任何根据这个模具生成出来的产品也自带了这些功能。

如果模板里面已经做好了一些功能,那么我的确可以使用这个模板,而不需要真正拿到一个产品。

比如生产一部手机,它的模板里面已经做好了一个手电筒的功能,那么,你即便不给我一个真正的产品,仅仅给我一个模板,我是不是也可以用它的手电筒功能呢?

这就是静态方法。

所以我们常说,静态方法和静态属性为所有实例共用,不就是这个道理吗?

所以,正常情况下,我们调用一个类的非静态方法,是不是必须要先new一个对象?

好的,我们现在来 根据 ArrayList 模板生产一个 ArrayList 产品

这样,我们才能调用它里面所有的非私有方法。

怎么生产呢,是不是new一下就可以啦?

2.2、 add方法

ArrayList是一个集合,既然是一个集合,那么它肯定是可以往里头添东西的。

怎么往里面添,用add,用add方法往里面加。

add的参数就是一个object,这就是多态,多态就是多种形态,多种身份的意思。object可以有多种形态。它可以是String,也可以是Integer,还可以是用户自定义的类型。

这里是不是又多态了。。。

这就是多态的一个用法。

2.3、 get 方法

既然能够往里面添加东西,是不是肯定还要拿出来啊。

怎么拿出来,用get方法拿出来,而且一次只能拿一个。不要多拿哦。

get 方法需要传入一个 int 类型的数字,这个数字就是元素对应的下标。

我们刚才第一个放进去的是 "HelloWorld" ,一个字符串。那么对应的下标就是0 。

第二个放进去的是new Integer(100),这是一个Integer对象,是一个实实在在的东西了。那么对应的下标就是1 。

现在,我取出第1个元素,应该是100。

试试看

报错了,因为 get 方法返回的是一个Object对象,而我们拿Integer 去接,就出问题了。

这是咋回事呢?

很简单,比如张三是一个医生,同时他还拥有一个人类的身份,可并不是所有的人类都是医生啊?

注意我下面分析的用词,能帮助你理解。

同理,Integer 是一个整数类型,同时它还拥有一个Object的身份,可并不是所有的 Object 都是Integer 啊?

同接口一样,A继承B,可以看成A同时拥有了B的身份。

如果A继续保持A的身份,那么它不仅拥有自己本身的能力,也拥有B的能力。只要A愿意,他完全可以展现B的能力。

如果A变身成为了B,那么它肯定不希望别人知道他是A。

就好比虽然他知道他可以变身成为奥特曼,但是一般情况下,他都不愿意曝露自己的身份。

所以如果A变身成为了B,那么A就只会使用B的能力,同时隐藏他本身的能力。

如果你是初学者,请仔细体会一下这其中的韵味。慢慢地,你就会对多态有一个更深入的理解。一段时间后,你再重新去看以前写的代码,会有不一样的感觉。

再举一个例子,帮助你理解。

我 new 一个 ArrayList :(在eclipse中)

换行,写上arrayList 。

我直接在arrayList 右边加一个点,然后会有提示:

这些都是它可以调用的方法和属性,哇,这么多。

如果我这样写呢?

我也在arrayList 右边加一个点

不好意思,你现在只能调用 Object 类的属性和方法了。

嗯,再体会一下。

初学者在面向对象方面的理解总是会走弯路,如果你能把这些东西理清,对今后的学习会有巨大的好处。

继续。

我们这里就强转一下吧,因为我们知道 index 为1的元素是一个Integer类型的。

结果

好的,是正确的。

2.4、 remove 方法

remove 方法可以删除集合中的元素,ArrayList给我们提供了很多删除元素的方法。

我们这里先看一下第一个方法。

这是通过数组下标来删除某一个特定的元素,我们刚才给ArrayList添加了两个元素,下标分别为 0,1 ,那么,如果我删除第0个元素,会怎么样呢?

首先,ArrayList的列表长度会不会改变?

我们可以通过size()方法来获取ArrayList当前的列表长度。

测试:

打印出来是1,看来的确是影响长度了。

2.5、 toArray 方法

这个方法可以将ArrayList转换成一个Object数组。

例:

需要注意的是,哪怕你给ArrayList全部添加Integer类型的元素,也不能采用这样的代码:

这是错误的,虽然编译的时候不会报错,但是运行无法通过。

因为ArrayList的add方法可以添加任意类型的参数,Java运行机制无法获知ArrayList中的元素是否可以都强制转换为你指定的类型。所以这种写法是不被允许的。

文/剽悍一小兔(简书作者)

原文链接:http://www.jianshu.com/p/8f4e6b6d4403

用大白话聊聊JavaSE相关推荐

  1. 转载:用大白话聊聊分布式系统

    转载:http://blog.csdn.net/zhousenshan/article/details/71304922?locationNum=10&fps=1 转载于:https://ww ...

  2. 兄弟,用大白话告诉你小白都能看懂的Hadoop架构原理

    本文来自:石杉的架构笔记 目录 一.前奏 二.HDFS的NameNode架构原理 一.前奏 Hadoop是目前大数据领域最主流的一套技术体系,包含了多种技术. 包括HDFS(分布式文件系统),YARN ...

  3. 用大白话彻底搞懂 HBase RowKey 详细设计

    来源 | 且听_风吟 来源 | CSDN 博客,责编 | Carol 封图 | CSDN 付费下载于东方 IC 前言 RowKey作为HBase的核心知识点,RowKey设计会影响到数据在HBase中 ...

  4. 用大白话彻底搞懂 HBase RowKey 详细设计!

    来源 | 且听_风吟 来源 | CSDN 博客,责编 | Carol 封图 | CSDN 付费下载于东方 IC 前言 RowKey作为HBase的核心知识点,RowKey设计会影响到数据在HBase中 ...

  5. 【面向对象】用大白话扯扯那神奇的面向对象编程思维(一)

    前言:每当提到面向对象的时候,初学者肯定都是一脸懵逼的状态,到底什么是面向对象?会用面向对象后有什么牛逼之处吗?不会用是不是就会死掉?答案肯定不会死掉,我们可以来简单的举一 个栗子 1.当你想到熊猫的 ...

  6. 兄弟,用大白话给你讲小白都能看懂的分布式系统容错架构

    点击上方"蓝字", 右上角选择"设为星标" 周一至周五早11点半!精品文章准时送上! 本文来自石杉的架构笔记 目录 (1)TB级数据放在一台机器上:难啊! (2 ...

  7. 干货!用大白话告诉你什么是Mock测试

    初识mock 作为一个动词,mock是模拟.模仿的意思:作为一个名词,mock是能够模仿真实对象行为的模拟对象. 在软件测试中,mock所模拟的对象是什么呢? 它一定不是我们所测试的对象,而是 SUT ...

  8. 用大白话讲解RxJava原理

    近日外媒报道称,Google 其应用商店 Play Store 一次下架了超过 600 个违规 App:其中中国.印度以及新加坡为本次大规模下架 App 开发者前三的国家,来自中国的猎豹移动所开发的 ...

  9. java用什么编译器_用大白话告诉你,Java到底是什么

    Java是什么 Java是一门编程语言,是一门连接人与计算机的语言. 由于计算机只认识二进制(只有0和1)的信息,对于我们来说,二进制的信息与我们平时所说的话比较起来就太难懂了,所以为了能够很好的和电 ...

  10. php csrf攻击 xss区别,用大白话谈谈XSS与CSRF

    这两个关键词也是老生常谈了,但是还总是容易让人忘记与搞混~. XSS与CSRF这两个关键词时常被拉出来一起比较(尤其是面试),我在这里也在写一篇扫盲文,也帮自己整理一下知识脉络. 这篇文章会用尽量&q ...

最新文章

  1. Mask R-CNN用于目标检测和分割代码实现
  2. js uri解码_js进行URL编码(escape,encodeURI,encodeURIComponent)
  3. C++函数编译原理和成员函数的实现
  4. 700 页的机器学习笔记火啦,图文生动形象
  5. 运维自动化之何为版本控制?
  6. 阿里云盘内测_阿里云盘 | 内测码分享 + 火速体验!
  7. Nuxt.js mini聊天室开发 (mini-chatroom)
  8. List,Map和Pojo互转,一行代码解决。多种实现
  9. 【raft】学习六:etcd/raft 选举和选举优化
  10. css 解决因为书名号不满一行就换行情况
  11. Mediapipe+OpenCV与Unity引擎实现动作捕捉
  12. Coreldraw2022cdr新版更新矢量图设计
  13. Qt延时和startTimer
  14. 7-10 黑洞数(20 分)
  15. nubia/努比亚Z5Sn(32GB) root教程_方法
  16. 商场会员营销小程序-连接会员,赋能商家
  17. 《JSP程序设计》报告
  18. Revit建模:楼板三维视图旋转模型如何使图案跟着旋转
  19. Vultr Debian8系统一键快速DD安装Windows7系统
  20. 总后台顶部实现站内信功能

热门文章

  1. android渠道首发规则,酷传推广手册Android渠道首发规则.doc
  2. 论文阅读及代码学习-Directed Acyclic Graph Network for Conversational Emotion Recognition
  3. 一名交互设计师必备的知识架构
  4. batchnomal_Linux Kernel 排程機制介紹 ? Loda's blog
  5. 太湖之光超级计算机应用最高奖,国家超级计算无锡中心发布:“神威·太湖之光”最新应用成果...
  6. 数据可视化之美+点、线、面组合(以Python为工具)
  7. 10年时间,打工妹把一个团队从“一盘散沙”到精英战队,成功实现空手“造”大房···
  8. JavaEE程序猿的Java世界观⑤
  9. 2017前端开发手册三-前端职位描述
  10. 红米pro位置服务器,数码产品:红米note8pro nfc感应区在哪 nfc位置