PS:
List和Set都有iterator()来取得其迭代器。对List来说,你还可以通过listIterator()取得其迭代器,两种迭代器在有些时候是不能通用的,Iterator和ListIterator主要区别在以下方面:
1. ListIterator有add()方法,可以向List中添加对象,而Iterator不能。Iterator是ListIterator的父接口。
2. ListIterator和Iterator都有hasNext()和next()方法,可以实现顺序向后遍历,但是ListIterator有hasPrevious()和previous()方法,可以实现逆向(顺序向前)遍历。Iterator就不可以。
3. ListIterator可以定位当前的索引位置,nextIndex()和previousIndex()可以实现。Iterator没有此功能。
4. 都可实现删除对象,但是ListIterator可以实现对象的修改,set()方法可以实现。Iierator仅能遍历,不能修改。
因为ListIterator的这些功能,可以实现对LinkedList等List数据结构的操作。其实,数组对象也可以用迭代器来实现。
org.apache.commons.collections.iterators.ArrayIterator就可以实现此功能。一般情况下,我们使用Iterator就可以了,如果你需要进行记录的前后反复检索的话,你就可以使用ListIterator来扩展你的功能,(有点象JDBC中的滚动结果集)
5 ListIterator中具备着对被遍历的元素进行增删改查的方法,可以对元素进行逆向遍历。
一 前言:讲集合collection之前,我们先分清三个概念:
colection 集合,用来表示一种数据结构(集合--逻辑结构的一种)
Collection 集合接口,指的是 java.util.Collection接口,是 Set、List 和 Queue 接口的超类接口
Collections 集合工具类,指的是 java.util.Collections 类。
Collection完整图---VS---重点学习图
重点学习图:(如下)
二 分别介绍
- List 关注事物的索引列表
- Set 关注事物的唯一性
- Queue 关注事物被处理时的顺序
- Map 关注事物的映射和键值的唯一性
(一) List
List接口:有序的列表,允许重复元素,它的有序是指假如元素时的顺序。
1) ArrayList: 数组列表。内部采用数组结构来存储元素, 根据索引来存取元素的效率很高
适合于:要遍历显示所有元素的情况。不适合需要频繁增删元素的情况。
2) LinkedList:链式列表。内部采用双向链表结构来存储元素.适合于:需要频繁增删元素的情况下。但不要使用根据索引来获取元素。
双向链表结构不仅可以后向迭代,还可以前向迭代,并且支持元素的修改。
ArrayList 可以将它理解成一个可增长的数组,它提供快速迭代和快速随机访问的能力。 LinkedList 中的元素之间是双链接的,当需要快速插入和删除时LinkedList成为List中的不二选择。
Vector 是ArrayList的线程安全版本,性能比ArrayList要低,现在已经很少使用.
Stack继承自Vector,实现一个后进先出的堆栈。Stack提供5个额外的方法使得Vector得以被当作堆栈使用。基本的push和pop方法,还有peek方法得到栈顶的元素,empty方法测试堆栈是否为空,search方法检测一个元素在堆栈中的位置。Stack刚创建后是空栈。
(二)Set
2) 常用的数据类型:8种基本数据类型包装类、String类、Date类、Calendar类它们
a) 散列表的存储原理:
a) 可排序的类必须实现java.lang.Comparable接口,在compareTo方法中定义比较规则。
int compareTo(T t);如果当前对象小于指定对象,返回负整数;大于,返回正整数。等于,返回0。
b) 为了便于使用各种排序规则的要求,可以通过实现Comparator<T>接口来定义比较器类。
int compare(T t1, T t2);如果t1对象小于t2对象,返回负整数;大于,返回正整数。等于,返回0。
TreeSet 当不希望集合中有重复值,并且希望按照元素的自然顺序进行排序时可以采用此类。(TreeSet采用红黑树的数据结构进行排序元素,使用它可以从 Set中提取有序(升序或者降序)的序列。需要注意的是,存入自定义类时,TreeSet需要维护元素的存储顺序,因此自定义类要实现Comparable接口并定义compareTo方法。若不实现Comparable接口/Comparator接口,则按自然顺序意思是某种和插入顺序无关,而是和元素本身的内容和特质有关的排序 方式,譬如“abc”排在“abd”前面。)
Set判断两个对象相同不是使用==运算符,而是根据equals方法。也就是说,只要两个对象用equals方法比较返回true,Set就不 会接受这两个对象。
当向HashSet结合中存入一个元素时,HashSet会调用该对象的hashCode()方法来得到该对象的hashCode值,然后根据 hashCode值来决定该对象在 HashSet中存储位置。 简单的说,HashSet集合判断两个元素相等的标准是两个对象通过equals方法比较相等,并且两个对象的hashCode()方法返回值相 等 。注意,如果要把一个对象放入HashSet中,重写该对象对应类的equals方法,也应该重写其hashCode()方法。其规则是如果两个对 象通过equals方法 比较返回true时,其hashCode也应该相同。另外,对象中用作equals比较标准的属性,都应该用来计算 hashCode的值。
(三)Queue(用于保存将要执行的任务列表。)
LinkedList 同样实现了Queue接口,可以实现先进先出的队列。
(四) Map ( Map关心的是唯一的标识符。他将唯一的键映射到某个元素。当然键和值都是对象。)
a) 作为映射对的键对应的类要重写equals和hashCode方法,以实现键相等规则。
b) 因为键是用散列表存放的,所以键/值对在Map中的存放是无序的。
c) 适合于:需要以键/值对形式存放元素时。它的存取效率很高。它是使用频率最高的一个集合类。
b) 另一种方式,把一个针对键的比较器(实现Comparator接口的类)对象传入该类的构造器来创建。
LinkedHashMap 当需要键值对,并且关心插入顺序时可采用它。LinkedHashMap保存了记录的插入顺序,在用Iterator遍历LinkedHashMap时,先得到的记录肯定是先插入的.也可以在构造时用带参数,按照应用次数排序。在遍历的时候会比HashMap慢,不过有种情况例外,当HashMap容量很大,实际数据较少时,遍历起来可能会比LinkedHashMap慢,因为LinkedHashMap的遍历速度只和实际数据有关,和容量无关,而HashMap的遍历速度和他的容量有关。LinkedHashMap也是一个HashMap,但是内部维持了一个双向链表,可以保持顺序。(因为是双向链表,其除了能向后遍历,还支持向前遍历,并可在遍历过程中删除元素)
TreeMap 当需要键值对,并关心元素的自然排序时可采用它。TreeMap实现SortMap接口,能够把它保存的记录根据键排序,默认是按键值的升序排序,也可以指定排序的比较器,当用Iterator 遍历TreeMap时,得到的记录是排过序的。不仅可以保持顺序,而且可以用于排序.
TreeMap取出来的是排序后的键值对。但如果您要按自然顺序或自定义顺序遍历键,那么TreeMap会更好。
LinkedHashMap 是HashMap的一个子类,如果需要输出的顺序和输入的相同,那么用LinkedHashMap可以实现,它还可以按读取顺序来排列,像连接池中可以应用。
三 列表、集合与数组的互相转换
1 List、Set转为数组
Set转换成数组可以使用Set的toArray方法,返回一个Object数组。
如果List或者Set中元素的 类型 都为 A,那么可以使用带参数的toArray方法,将得到类型为A的数组,具体语句是(A[])set.toArray(new A[0]),例: ArrayList<Integer> lt=new ArrayList<Integer>();