01Java集合框架
Java的集合类库将接口(interface)与实现(implementation)分离。
首先是队列:队列接口指出可以在队列尾部添加元素,在队列头部删除元素,并且查找队列中元素的个数。其方式是先进先出。
队列有两种实现方式:一十循环数组,另一种是使用链表。
循环数组是一个有界集合,即容量有限;若程序中要收集的对象数量没有上限,则使用链表。
集合类的基本接口是Collection接口。
其中有一个迭代器,可以通过反复调用next方法,逐个访问集合中的每个元素。注:可以认为Java迭代器位于两个元素之间,当调用next时,迭代器就越过下一个元素,并返回刚刚越过的那个元素引用。
02集合框架中的接口
Java集合框架为不同类型的集合定义了大量接口。集合有两个基本接口:Collection和Map。
通过映射插入元素,由于映射包含键值对,故使用put
List是一个有序集合。元素会怎该到容器中特定位置。可以使用迭代器访问,或者使用一个整数索引访问。后者这种方法称为随机访问(因为可以按任意顺序访问元素)。
数组支持快速的随机访问,但是链表随机访问很慢,最好使用迭代器。
set接口同样实现collection接口。set集的add方法不允许增加重复元素。其equals方法只要两个集包含同样的元素就认为相等,并不要求顺序。
03具体集合
1.链表
数组删除一个元素的开销很大,因为删除一个元素之后的元素都要向数组前端移动。增加同理。并且链表是将每个对象存放在单独的链接中,每个链接还存放着序列中下一个链接的引用。链表实际都是双向引用的。
链表删除元素的开销很小,只需要更新其周围的引用即可。
2.数组列表
List接口以及实现了这个接口的各个类,包括我们熟悉的ArrayList类。
3.散列表
数据结构中,运用散列表可以快速地查找对象散列表为每一个对象计算一个整数,称之为散列码(hash code)。
散列表采用链表数组实现,每个列表被称为桶。要查找位置,就要计算其散列码,再与桶的总数取余,所得到的结果就是保存这个元素的桶的索引。(遇到桶已经被填充现象称为散列冲突)
填装因子。一般设为0.75,即表已经被填满75%以上,就会自动再散列,新表的桶数是原来的两倍。
4.树集
TreeSet,是一个有序集合,可以以任意顺序将元素插入到集合中。对集合进行遍历时,值将自动地按照排序后的顺序呈现。
5.队列与双端队列
双端队列允许在头部和尾部都高效的添加或者删除元素.
6.优先队列
优先队列的元素可以按照任意的顺序插入,但会按照有序的顺序进行检索。即,无论何时调用remove都会获得当前优先队列,都会获得当前队列的最小元素。
优先队列采用堆(heap)结构,堆是一个可以自由组织的二叉树,其添加或者删除可以将最小元素移动到根,而不必花费时间排序。
04映射
当我们获得了一些关键信息,并希望以此来查找与之关联的元素,那么映射结构就是我们所需要的。映射存放键值对,通过键就能查找值。
基本映射操作:Java提供了映射两个通用实现:HashMap和TreeMap。其组织形式与集一样,访问特点亦类似。
注意,映射中键必须是唯一的,一个键只能存放一个值如果对一个键使用两次put方法,那么第二个值就会取代第一个。
集合框架不认为映射本身是一个集合,不过我们可以得到映射的视图通过实现collection接口或者子接口对象。共有三种视图:键集,值集合以及键值对集。
弱散列映射:WeakHashMap使用弱引用保存键,在垃圾回收时,引用对象的弱引用会进入队列。同时WeakHashMap会周期性检查队列,删除弱引用相关映射条目。
链接散列表与映射:LinkedHashSet和LinkedHashMap会记住插入元素的顺序。可以避免散列表中的项看起来是随机的。
05视图与包装器
不可修改视图:生成的不可修改视图会对现有集合增加一个运行时检查若发现修改会抛出异常。
同步视图:多线程访问集合,必须确保集合不会被意外破坏。synchronizedMap方法可以把映射转换成同步访问方法。
06算法
泛型算法由于其算法只需要实现一次,优势很大。
例如比较可以使用a.comparedTo(b).
排序:集合类库中使用的排序算法比快速排序(通用排序算法的传统选择)要慢一点,但是归并排序的一个优点是稳定。
一些相关术语的定义:若列表支持set,可修改;若支持add与remove可以改变大小。
二分查找:binarySearch,注意二分查找时集合必须有序。
集合与数组转换:数组转为集合,可以采用List.of包装器,从集合到数组可以采用toArray方法,不过返回的是一个Object[]数组,需要返回指定类型需要使用toArray的一个变体。
07遗留集合
包括HashTable类与HashMap类似,枚举类等。
属性映射:属性映射是一个特殊类型的映射结构。其有3个特性:
键与值都是字符串;
这个映射可以很容易地保存到文件以及文件加载;
有一个二级表存放默认值;
实现Java平台类名叫Properties。属性映射对于指定程序的配置选项很有用。
Properties类有两种提供默认值的机制。第一种方法是,只要查找一个字符串的值,可以指定一个默认值,这样当键不存在时就会自动使用这个默认值。当然也可以把所有默认值都放在一个二级属性映射中,并在主属性映射的构造器中提供这个二级映射。
栈:stack类,有put和pop方法。
位集:位集可以高效的存储位序列,由于位集将位包装在字节里,所以使用位集要比使用Boolean和ArrayList高效。