毕业这么久,java 标准库中的集合都没怎么仔细了解过,准备好好学习学习。
集合(Collection):由一个或多个确定的元素所构成的整体叫做 集合--百度百科的解释。换言之,就是装元素的容器,元素可以是任何类型。
在我们的日常开发,这类工具是必不可少的,所以,好好了解他们的特性,能让我们写出更合适的代码,也是在修炼内功。
------------------------------------------------------------------------------------------
在 Java 中的集合,我觉得可以分类两类:有序集合(List : 元素按照一定顺序排列) 和 无序集合(Set : 元素是无序的,此特性也决定了元素是不可重复的)。
对于集合,有一个不可缺少的辅助工具,那就是迭代器(Iterator),为什么这么说呢?我们看看 java 中的代码
Collection 接口:
从上边代码中可以,在 Collection 接口中, 有一个 Iterator<E> iterator() 方法,这个方法返回:一个实现了 Iterator 接口的对象。利用这个迭代器对象可以依次访问集合中的对象。
Iterator 接口:
想必大多数人都使用 迭代器 遍历集合,有了上边的 hasNext() 和 remove() 方法,就可以做到,如下:
List<String> list = new ArrayList<String>(); Iterator iter = list.iterator(); while( iter.hasNext() ){//如何还有元素 String element = iter.next();//获取元素 //do something with element }
但是,有人看到了上边的代码,可能会觉得有点繁琐,那么 java 提供一种更加简介的方式:for each 循环。
for ( String element : list ){ //do something with element; }
简洁换来的代价就是,该集合必须是实现了 Iterable 接口,这个接口的定义如下:
forEach 方法和 spliterator 方法:都是default方法(java8 之后就开始允许这种骚操作,提供默认实现,不强制实现。参考:http://blog.csdn.net/lin6286878/article/details/53464804),所以,实现 Iterable 接口时,只需要实现 iterator方法即可。
那么在 java 中,Collection 接口都扩展了 Iterable 接口,那么,就代表 集合对象都可以使用 for each 达到遍历的目的
----------------------------------------------------------------------------------------------------
知道了 集合 和 迭代器的 关系之后,ArrayList对象具有 数组的特性,那么操作起来跟数组差不多;不必多说,我们说说 LinkList 对象。
LinkList 对象中的 add 方法,每次都是在链表的尾部添加元素,如果我想要在 ListList 对象某个特定位置插入元素呢?放心,java 为我们提供了 ListIterator 接口,在 Iterator 接口基础上增加了 add 方法,保证了在链表可以在任何位置插入元素。迭代器中的指针是指向两个元素之间,那么插入元素的位置位 集合元素个数 + 1。
既然迭代器这么方便,那么能不能多个迭代器 同时作用于 同一个集合,答案是:可以的,但是有且只有一个迭代器能对集合进行改变(其他只能读)。
如果多个迭代器可以改变,那么集合的数据就会变得很乱,那么如何保证有且只有一个迭代器对集合进行修改呢?
1)每个迭代器维护一个 该写操作的计数器,
2)集合本身维护一个 改写操作的计数器,
3)每个迭代器开始处检查 两个计数器的值 是否一致,如果一致,则通过,否则 抛出 ModificationException 异常。