集合与集合框架
集合是某一个对象的通称呼,这个对象代表以某种方式组合到一起的一组对象;它是将多个元素组合为一个单元的对象,用于存储,检索,操纵和传递数据。
我们谈到对象的集合时,指的是对象引用的集合而不是对象的集合,在JAVA集合中只存储引用,对象在集合之外。
集合框架提供用于管理对象集合的接口和类,它包括接口,实现和算法。
JAVA中三种重要的集合类型:集Set,序列Sequence和映射Map.
集Set
不按任何特定的方式排列:集中每一个对象都是唯一的;通过对集中对象的引用删除对象;集的变体(集可以排序)要求定义存储对象的类能实现运用于对象比较的方法。
序列 Sequence
有叫列表List,对象以线性方式存储,没有特定的顺序,只有一个开头和一个结尾(普通的数组实际上是一个列表)。
由于列表是线性的,所以只能在列表的开头或结尾处添加新对象,或者在序列中指定的对象后面插入对象。在列表中检索(删除)对象是非常灵活的:可以选择第一个或最后一个对象,可以得到指定位置的对象(就像索引数组一样),也可以通过先前或向后顺序搜索序列中的所有对象,找出与给定对象相同的对象,还可以用迭代的方式按向前或向后的顺序访问序列中的每一个对象(序列在不同位置可以保存同一对象的不同副本)。
列表在数据结构中分别表现为:数组和向量、链表、堆栈、队列。堆采用后进先出的存储机制,也是一种列表;队列采用先进先出的存储机制,也被看作一种列表;链表可以像栈一样工作,这很好理解,因为只要采用在链表的表尾添加和删除对象的方法,链表就和栈一样了;同样,采用某种方法只在链表尾插入对象,而从链表头检索对象,链表就可以像队列一样工作了。
映射Map
关键字(Key)决定了对象在映射中的存储位置;它可以是任何类型的对象;它在一个映射中必须是唯一的;并且它决定了关键字/对象在映射中存储的位置,本质上由散列(hashing)处理关键字,产生一个别称作散列码(hashcode)的整数值,实际上是相对于分配给映射的内存区域起始位置的偏置量。Object中定义的HashCode()方法为一个对象生成int型散列码。
迭代器
在Java语言中,迭代器是可以由集合类实现的一个接口,任何集合对象都可以创建Iterator类型的对象,该对象把原始集合中的所有对象的引用按照某种顺序封装起来(封装对原始集合引用的引用),并且可以使用Iterator接口定义的方法访问该对象。换句话说,迭代器提供了一个简单的方法,一次一个地得到集合中的所有对象。
(1) boolean hasNext(): 判断是否存在另一个可访问的元素
Object next(): 返回要访问的下一个元素。如果到达集合结尾,则抛出NoSuchElementException异常。
(2) void remove(): 删除上次访问返回的对象。本方法必须紧跟在一个元素的访问后执行。如果上次访问后集合已被修改,方法将抛出IllegalStateException。
Iterator iter = myCollection.iterator ();
Myclass item;
While (iter.hsaNext ()){
item=(Myclass)iter.next();
// do something with item
}
“Iterator中删除操作对底层Collection也有影响。”
迭代器是故障快速修复(fail-fast)的。这意味着,当另一个线程修改底层集合的时候,如果您正在用 Iterator 遍历集合,那么,Iterator就会抛出 ConcurrentModificationException (另一种 RuntimeException异常)异常并立刻失败。
“Java语言也提供了一种称为计数器(enumerator)的机制,enumerator提供的功能基本上与Iterator相同,但Java语言文档中建议,在处理集合时使用Iterator比使用Eumerator好。”
列表迭代器 ListIterator
ListIterator接口说明了一些能向前或向后遍历集合对象的方法。ListIterator没有当前位置,光标位于调用previous和next方法返回的值之间。一个长度为n的列表,有n+1个有效索引值:
(1) void add(Object o): 将对象o添加到当前位置的前面
void set(Object o): 用对象o替代next或previous方法访问的上一个元素。如果上次调用后列表结构被修改了,那么将抛出IllegalStateException异常。
(2) boolean hasPrevious(): 判断向后迭代时是否有元素可访问
Object previous():返回上一个对象
int nextIndex(): 返回下次调用next方法时将返回的元素的索引,如果ListIterator对象位于列表的尾部,则返回列表中元素的个数。
int previousIndex():返回下次调用previous方法时将返回的元素的索引,如果ListIterator位于列表的头部,则返回-1。
“正常情况下,不用ListIterator改变某次遍历集合元素的方向 — 向前或者向后。虽然在技术上可以实现,但previous() 后立刻调用next(),返回的是同一个元素。把调用 next()和previous()的顺序颠倒一下,结果相同。”
“我们还需要稍微再解释一下 add() 操作。添加一个元素会导致新元素立刻被添加到隐式光标的前面。因此,添加元素后调用 previous() 会返回新元素,而调用 next() 则不起作用,返回添加操作之前的下一个元素。”