JavaSE中Collection集合框架学习笔记(1)——具有索引的List
前言:因为最近要重新找工作,Collection(集合)是面试中出现频率非常高的基础考察点,所以好好恶补了一番。
复习过程中深感之前的学习不系统,而且不能再像刚毕业那样死背面试题,例如:String是固定长度的,StringBuffer和StringBuilder的长度是可以变化的。如果一旦问得深入一点,问为什么有这样的区别就傻眼了,只能一脸呆萌地看着面试官。
因此想要通过写文章的形式,系统地总结学习的内容,例如Collection架构是怎样的、有哪些相关的继承和接口实现,这样才能了解什么时候应该用哪个类,以及类之间要如何搭配合作,才知道出了问题应该如何解决。这一系列文章适用于Java技术岗的应聘者、高校计算机专业的学生以及培训机构学习Java的初学者阅读。
1.1 认识Collection架构
我们都使用过ArrayList类收集对象,例如add()方法新增对象,remove()方法移除对象,这些都不会陌生。但是这些方法是怎么来的呢?下图是该类的继承架构图:
ArrayList一个类就这么复杂,如果要把全部Collection架构表现在一张图上,那估计就跟蜘蛛网一样纠缠不清。简化一下,忽略一些不那么重要的接口和实现类,我们可以得到以下这张架构图。
从图上可知,Colletion是一个接口,实现了另一个接口Iterable。Collection下面有三个接口直接实现了它,分别是List、Set和Queue。List下面有两个实现类,分别是ArrayList和LinkedList;Set的常用实现类是TreeSet和HashSet;Queue下面有Deque接口实现,再下面是实现类ArrayDeque.
这张图将会是这一系列文章的核心,之后会反复提及,不妨称之为Collection架构图,每一篇文章都是介绍其中的一部分。熟悉这张图,不仅有助于理解学习,还可以帮助记忆。至于详细周全的继承关系和实现架构,到底有哪些类实现了哪些接口、继承了哪些类,可以自行在API说明文档中查询。
1.2 具有索引的List
List实现了Collection接口,所以我们可以说List是一种Colletion,作用就是收集对象,特点是以索引的方式记录所收集的对象顺序。List中常见的实现类是刚才所提及架构图中的ArrayList,忘了的读者可以翻到前面对照着看。
/**
* ArrayList的实验用例
*/ import java.util.*; public class Student {
public static void main(String[] args) {
List list = new ArrayList(); //使用JavaSE的List和ArrayList
Scanner scanner = new Scanner(System.in);
String name;
while(true) {
System.out.print("学生签到:");
name = scanner.nextLine();
if(name.equals("quit")) {
break;
}
list.add(name); //实用Add()方法收集对象
}
System.out.println("今天上来上课的学生名单:");
foreach(list);
} private static void foreach(List list) {
for(int i = 0; i < list.size(); i++) {
String student = (String) list.get(i); //使用get()方法依据索引取得收集的对象
System.out.println(student);
}
}
}
以上是ArrayList类的一个简单使用例子,模拟的是学生上课签到的情景。强烈建议读者跟我一样自己试着写一个简单用例,尤其是之前很少使用ArrayList的初学者,单纯的看和读跟实际敲代码产生的效果完全不一样。也可以照着我给出的例子敲,偷懒一点的话可以直接复制在机器上跑一遍。
从Collection架构图中可知,LinkedList同样也实现了List接口。就算只是把上面那个实验中的ArrayList全部改为LinkedList,程序照样可以运作,而且效果看起来完全相同。那么问题来了,我们什么时候应该使用ArrayList,什么时候又应该使用LinkedList呢?
1.2.1 ArrayList的特性
卡车和轮船都可以运送货物,我们可以根据不同的情况选择不同的运输方式。如果时间紧、运输量小,而且两个地点都在陆地上(例如北京到南京),那么我们可以使用汽车;如果时间多、运输量大,出发地和目的之间隔着海洋(例如大连到纽约),那么用船运是更好的选择。
刚毕业那会要找工作,为了面试背过“ArrayList像数组,读取速度快,但是需要调整索引的话表现很差;LinkedList像链表,调整索引的表现非常好,但是随机读取的速度比较慢”。那么我们可以问深一句,为什么会这样呢?不妨从源代码中找寻答案。
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
上面这一段是JavaSE的源代码,我们可以看到ArrayList中的add()方法非常简单,跟我们平时使用数组一样。查看源代码中更多内容你会发现,ArrayList内部就是使用Object数组来保存所收集的对象,这就是为什么说“ArrayList就像数组”的原因。在考虑是否使用ArrayList的时候,我们可以相当于考虑是否要使用数组的特性。
1.2.2 LinkedList的特性
在学习Collection架构的时候,我们不妨可以多看源代码,看的时候优先比较几个基本方法的实现,例如add()、remove()等。从这些方法的实现,我们就可以看到不同实现类的特性。
public boolean add(E e) {
linkLast(e);
return true;
} /**
* Links e as last element.
*/
void linkLast(E e) {
final Node<E> l = last;
final Node<E> newNode = new Node<>(l, e, null);
last = newNode;
if (l == null)
first = newNode;
else
l.next = newNode;
size++;
modCount++;
}
看到LinkdedList.add()的源代码,我们会发现其实现方式跟链表的实现如出一辙。如果last结点为null,那么说明链表为空,所以新添加的结点为头结点。如果last结点不等于null,那么把新添加的结点设为last的下一个结点,作为新的尾结点。
根据链表的特性,我们可以很快总结两点点特性:1.想要指定索引随机存取时,链接方式都得使用从第一个元素开始查找下一个元素的方式,效率比较糟糕;2.链接的每个元素都会参考下一个元素,这有利于调整索引顺序。
1.2.3 List总结
作为Collection三大阵营之一的List,最大的特点就是索引,我们可以通过索引做到随机存取。
List中常用的实现有ArrayList和LinkedList,各自的特性可以分别参考数组和链表。在比较它们之间区别的过程中,我们看了源代码,提倡在比较同一接口不同实现类时重点查看它们共同需要实现的方法,例如Collection中规定的add(),remove()等。
面试中常见的List实现类其实还有Vector,其特性与ArrayList相同。不同在于Vector具有线程安全的特性,性能开销比较大,具体的内容会放在以后关于多线程的文章里。
在总结过程中,给初学者提供两个建议,一是做实验,通过写一些demo来熟悉所学内容;二是在力所能及的情况下多看源代码,知其然也要知其所以然。
如果你喜欢我的文章,可以扫描关注我的个人公众号“李文业的思考笔记”。
不定期地会推送我的原创思考文章。
JavaSE中Collection集合框架学习笔记(1)——具有索引的List的更多相关文章
- JavaSE中Collection集合框架学习笔记(2)——拒绝重复内容的Set和支持队列操作的Queue
前言:俗话说“金三银四铜五”,不知道我要在这段时间找工作会不会很艰难.不管了,工作三年之后就当给自己放个暑假. 面试当中Collection(集合)是基础重点.我在网上看了几篇讲Collection的 ...
- JavaSE中Collection集合框架学习笔记(3)——遍历对象的Iterator和收集对象后的排序
前言:暑期应该开始了,因为小区对面的小学这两天早上都没有像以往那样一到七八点钟就人声喧闹.车水马龙. 前两篇文章介绍了Collection框架的主要接口和常用类,例如List.Set.Queue,和A ...
- Java集合框架学习笔记
集合类的由来:对象用于封装特有数据,对象多了需要存储,如果对象的长度不确定,就使用集合存储. 集合特点1.用于存储对象的容器.2.集合的长度可变.3.集合中不可以存储基本类型 集合容器因为内部的数据结 ...
- 集合框架学习笔记<二>
1.什么是ArrayList ArrayList就是传说中的动态数组,用MSDN中的说法,就是Array的复杂版本,它提供了如下一些好处: 动态的增加和减少元素 实现了ICollection和ILis ...
- 集合框架学习笔记<三>
一些重要的区别 set与list的区别: set是无索引的,list是有索引的: ArrayList与LinkList的区别: 前者是基于数组实现的,后者是基于链表实现的: 两者的使用方法一样,但是在 ...
- JavaSE中Map框架学习笔记
前言:最近几天都在生病,退烧之后身体虚弱.头疼.在床上躺了几天,什么事情都干不了.接下来这段时间,要好好加快进度才好. 前面用了三篇文章的篇幅学习了Collection框架的相关内容,而Map框架相对 ...
- JavaSE中线程与并行API框架学习笔记1——线程是什么?
前言:虽然工作了三年,但是几乎没有使用到多线程之类的内容.这其实是工作与学习的矛盾.我们在公司上班,很多时候都只是在处理业务代码,很少接触底层技术. 可是你不可能一辈子都写业务代码,而且跳槽之后新单位 ...
- JavaSE中线程与并行API框架学习笔记——线程为什么会不安全?
前言:休整一个多月之后,终于开始投简历了.这段时间休息了一阵子,又病了几天,真正用来复习准备的时间其实并不多.说实话,心里不是非常有底气. 这可能是学生时代遗留的思维惯性--总想着做好万全准备才去做事 ...
- Yii框架学习笔记(二)将html前端模板整合到框架中
选择Yii 2.0版本框架的7个理由 http://blog.chedushi.com/archives/8988 刚接触Yii谈一下对Yii框架的看法和感受 http://bbs.csdn.net/ ...
随机推荐
- MyBatis之简单了解Plugin
MyBatis的Configuration配置中有一个Plugin配置,根据其名可以解释为"插件",这个插件实质可以理解为"拦截器"."拦截器&quo ...
- Bootstrap学习笔记之文本对齐风格
文本对齐风格 在排版中离不开文本的对齐方式.在CSS中常常使用text-align来实现文本的对齐风格的设置.其中主要有四种风格: ☑ 左对齐,取值left ☑ 居中对齐,取值center ☑ ...
- 利用R语言进行交互数据可视化(转)
上周在中国R语言大会北京会场上,给大家分享了如何利用R语言交互数据可视化.现场同学对这块内容颇有兴趣,故今天把一些常用的交互可视化的R包搬出来与大家分享. rCharts包 说起R语言的交互包,第一个 ...
- android studio 2.32躺坑记
按说这是没啥记录意义的.不过作为一个偶尔用一下ADT开发安卓程序的跨界老码农,遇到一个尴尬事,现在手机已经用上安卓6了,而电脑里的ADT里SDK还是18,19.越来越多的项目是android stud ...
- Finding Similar Users-Euclidean Distance Score
Purpose: Finding Similar Users Method: Euclidean Distance Score ex2.py critics={'Lisa Rose': {'Lady ...
- 一天搞定CSS: 清除浮动(float)--13
上一节已经说明了为什么要清除浮动了.这里我们就来解决浮动产生的各种问题. 为什么要清楚浮动? 地址:http://blog.csdn.net/baidu_37107022/article/detail ...
- Python中Swithch Case语法实现
而python本身没有switch语句,解决方法有以下3种:A.使用dictionaryvalues = { value1: do_some_stuff1, value2: do_some_stuff ...
- boost.property_tree读取中文乱码问题正确的解决方式
开发项目的时候在使用boost,在宽字符下遇到中文乱码问题 上网上看大家都是先转成utf8在进行解析的,例如: http://blog.csdn.net/hu_jiangan/article/deta ...
- Mybatis学习(二) - CRUD操作(增删改查操作)
直接上例子: 1.项目结构: 2.具体代码及配置 User.java package com.mybatis.bean; public class User { private int id; pri ...
- js判断是否是ie浏览器且给出ie版本
之前懒得写判断ie版本js,因为网上关于这方面的代码太多了,所以从网上拷贝了一个,放到项目上才发现由于时效性的问题,代码不生效.就自己写一个吧. 怎么去看浏览器的内核等信息 ---- js的全局对象w ...