1、Java的容器类,框架结构图
上图中:
- 虚线框中的是接口,实线框是具体的实现类。
- 虚线空心箭头为实现接口,实现空心箭头为继承类。
- 实心剪头为生成,Collection类可以通过Iterator()方法得到Iterator对象。
- Map实现类可以通过entrySet(),Values()方法得到Set容器等。
2、为什么要使用容器?
- 数组长度固定,应对不确定元素容量、大小的场景时,无法解决问题。
- 除了序列式的存储,还应有映射式。
- 不同的容器有不同的存储规则。
3、容器的整体结构是怎么样的?
- 整体分为2个部分:
- Collection类:存储单元素的序列
- Map类:存储(key:value)的键值对序列
- Collection类下分为2大类(Queue接口可以被List中的LinkedList实现)
- List:分为线性存储和链式存储,即ArrayList和LinkedList
- Set:有HashSet、TreeSet、LinkedHashSet
- 额外的关于Queue接口:PriorityQueue和LinkedList都实现了Queue接口,是其实现类。
- Map类就是其实现类:
- HashMap
- TreeMap
- LinkedHashMap
4、这些具体的实现类有什么特性、方法?
ArrayList
其底层实现是可以扩容的数组。
所以该容器对于查询、读取、修改操作的效率很快,但是对于增添、删除的操作较慢。
LinkedList
链表。
其查询、读、改的操作比较慢,需要从头遍历,增添、删除很快。
其实现了Queue接口,可以有队列的方法。有入队、出队等方法
同时其也可以实现Stack。有出栈、入栈等方法
一些方法有:增删改查、判断某序列是否是子列、截取子列等
PriorityQueue
在Queue的基础上。不是简单的自然排序
而是根据自己的优先需求,重写了Compartor接口的抽象方法。
在入队、或者出队时,根据比较排序,按优先级出队。
故名:优先级队列
HashSet
特性是:整个容器中某一个对象,只能唯一。
利用散列函数,加快了查询速度。
方法具体的有:增加、删除、判断是否存在某个对象等
TreeSet
特性同上。
底层实现是:红黑树
添加会自动按升序进行排序。
LinkedHashSet
按照添加的顺序排列的散列表。
保留了顺序的同时,也是使用散列表实现,保证了查询速度。(好像是维护了一张表,来存储加入的顺序)
HashMap
Map可以用过键查找值、且键是唯一的。
且可以嵌套:一个人可以映射到一个集合,这个集合里存了该人的多个宠物。(可以一对多,不可以多对一)
散列函数实现,故而查询速度很快。
TreeMap
同上。
LinkedHashMap
同LinkedHashSet,只是多了Map的特性。
最后。Map唯一和Collection的交集就是:可以用过entrySet和values方法生成集合的相关类,可以通过Iterator遍历等。
5、Utilities
图中还有2个工具类。
-
Arrays
-
Collections
他们有一些功能方法,具体的可以要使用时查看。
6、Iterator和ListIteartor
ListIterator是Iterator的子类。
List的相关容器可以通过ListIterator()方法得到它。
它有一些只针对List容器的方法,如双向遍历等。
7、Foreach与迭代器
foreach除了用于数组,还可以用于任何的Collection对象。
之所以能用,是因为有一个Iterable的接口,该接口包含一个能够产生Iterator的iterator()方法,并且Iterable接口被foreach用来在序列中移动。
因此如果你创建了任何实现Iterator的类,都可以将它用于foreach语句中。
适配器方法惯用法
当你有一个接口并需要另一个接口时,编写适配器就可以解决问题。
这里,我们希望在默认的前向迭代器的基础上,添加产生反向迭代器的能力,因此我不能使用覆盖,而是添加了一个能够产生Iterable对象的方法,该对象可以用于foreach语句。这样就可以提供多种foreach方式了。
在使用foreach语句是调用它即可。
如:Iterator
for(String str : ral.reversed())
这种适配器方法。
不改变原有的iterator()。
而是创建一个新的方法,在该方法内部,重写iterator()的实现,实现额外的功能适配,再返回。