本篇是《Android逆向入门教程》的第三章第7节,具体课程详情可点击下方图片查看:
每一章节详细内容及实验材料可通过加入底部免费的【Android逆向成长计划】星球获得!
0x01 基本概念
在我们开发程序中经常会与数据打交道,而我们一般是通过”容器”来容纳和管理数据。那什么是“容器”呢?生活中的容器不难理解,是用来容纳物体的,如锅碗瓢盆、书包和快递箱等。程序中的“容器”也有类似的功能,就是用来容纳和管理数据。
实际上,我们之前学习的数组就是一种容器,可以在其中放置对象和相同类型的一组数据。而数组的容量是事先定义好,不能随着需求的变化而扩容。基于数组并不能满足我们对于“管理和组织数据的需求”,所以我们需要一种更强大、更灵活、容量随时可扩的容器来装载我们的对象。这就是我们要学习的容器,也叫集合。容器的接口层次结构图如图所示:
Java容器类类库的用途是保存对象,可以将其分为2个概念:
- Collection:独立元素的序列,这些元素都服从一条或多条规则。List、Set都是Collection的一种,List必须按照顺序保存元素,而Set不能有重复元素。
- Map:Map是键值对类型,允许用户通过键来查找对象。Hash表允许我们使用另一个对象来查找某个对象。
0x02 Collection接口
1)List的特点及实现类
List是有序、可重复的容器。List中每个元素都有索引标记。可以根据元素的索引标记访问元素,从而精确控制这些元素。List允许加入重复的元素。更准确的来说,List通常允许满足 e1.equals(e2) 的元素重复加入容器。List接口常用的实现类有3个:ArrayList、LinkedList和Vector。
2)ArrayList
ArrayList底层是用数组实现的存储。ArrayList是长度可变数组,元素以线性方式连续存储,内部允许存放重复元素。允许对元素进行随机的快速访问,但是向ArrayList中插入和删除元素的速度较慢。ArrayList是非线程安全的。数组进行扩容时,会将老数组中的元素重新拷贝一份到新的数组中,每次数组容量的增长大约是其原容量的1.5倍。
特点:查询效率高,增删效率低,线程不安全。
3)LinkedList
LinkedLis底层用双向链表实现的存储,内部采用双向循环链表实现,插入和删除元素的速度较快,随机访问的速度较慢,LinkedList也是非线程安全的。
特点:查询效率低,增删效率高,线程不安全
4)Vector
Vector底层是用数组实现的List,相关的方法都加了同步检查,所以Vector线程安全,效率低。
特点:线程安全,效率低。
0x03 Set接口
Set接口继承Collection接口,Set容器的特点上面也提及过,无序不可重复。Set的常见实现类有HashSet、TreeSet等,我们一般使用HashSet。举例如下:
0x04 Map接口
Map就是用来存储“键(key)-值(value) 对”的。Map类中存储的“键值对”通过键来标识,所以“键对象”不能重复。Map在实际开发中使用非常广,特别是HashMap。put进行添加值键对,containsKey验证主要是否存在、containsValue验证值是否存在、keySet获取所有的键集合、values获取所有值集合、entrySet获取键值对。举例如下:
执行结果如下:
0x05总结
在后续协议分析实战中,我们会经常见到关于HashMap的用法,学会HashMap的使用对于后续的逆向分析是非常有帮助的。
在这里关于java的课程讲解就这么多了,很多细节以及实际操作在文章中并未讲出,如果想要更深入细致的学习可以去网上寻找相关java视频教程,不过我个人建议仍然是先了解个大概,需要用到时再去学习也不迟,希望大家能对之前讲解的文章耐心的阅读下来。
团队公开知识库链接:
https://www.yuque.com/whitecatanquantuandui/xkx7k2