[置顶] 有关ListIterator接口的add与remove方法探究
ListIterator接口继承自Iterator接口,新增了add()等方法。
关于ListIterator的add()方法的作用(接口是没有方法实现的,但其实现类对于add()方法的实现机制大致相同,姑且这样说吧),《java核心技术 卷I》里如下表述:
“如果多次调用add方法,将按照提供的次序把元素添加到链表中。它们被依次添加到迭代器当前位置之前。”
对于这种说法,很容易引发歧义,当前位置是什么?当前指向的元素,还是游标位置?
带着这种疑问,我查阅了ListIterator接口的API说明文档(网址见本文结尾),得到对于add()方法的如下英文描述:
Inserts the specified element into the list (optional operation). The element is inserted immediately before the element that would be returned by
, if any, and after the element that would be returned by next()
, if any. (If the list contains no elements, the new element becomes the sole element on the list.)previous()
该描述就很清晰:的确是把新元素插入由next()所返回的那个元素之前,previous()所返回的元素之后。之所以加之前与之后两个限定,是为了应对在链尾(next返回为空)以及链头(previous返回为空)的特殊情况,如果链表为空,则新插入的元素就作为该链表的唯一元素。另外,每当插入一个元素以后,迭代器都会后移(向着链尾方向)一位。
举例说明:
List<String> name=new LinkedList<String>(); name.add("A"); name.add("B"); name.add("C"); ListIterator<String> iter = name.listIterator(); iter.next(); iter.add("D"); iter.add("E"); for(String nm:name) System.out.println(nm);
第4行代码执行完毕,name链表内容如下1A2B3C4(数字只作为占位符,可以忽略,内容为ABC,从链头到链尾)
第5行定义迭代器以后,初始迭代器的位置是在数字1,执行第6行next以后,迭代器指向数字2的位置,此时如果再执行next(),返回B,执行previous(),返回A,因此应把D插入AB之间,迭代器顺移到DB之间;依次类推,可以插入E。最终输出结果为:
A D E B C
下面再简单看一下remove方法,关于remove方法,API文档描述如下:
Removes from the list the last element that was returned by
ornext()
(optional operation). This call can only be made once per call to previous()
next
orprevious
. It can be made only if
has not been called after the last call to add(java.lang.Object)
next
or previous
.
简单解释一下,要执行remove,首先要找到所需移除的元素,怎样找?当然是通过next()跟previous()方法,所以remove必须要跟在next()或是previous()之后,而且只能执行一次(一个元素当然只能删一次,删多个元素,需要再执行next()或previous())。另外,在执行next()或previous()后还不能先执行了 add()方法。因为,否则add()方法执行以后,迭代器已经移动了,这样所要删除的目标元素指向不明,会报”Unknown Source“异常。
所以《java核心技术 卷I》对add和remove方法总结如下:add方法只依赖迭代器的位置(next和previous各返回什么元素),而remove方法依赖于迭代器的状态(是否执行了next或remove方法)。(红色是我的备注)
对于java API文档,推荐GrepCode,网址如下:
这里你能看到类或接口的继承以及实现结构,同时还能查看实现源码,很不错。