总结不同点
我们在使用List,Set的时候,为了实现对其数据的遍历,我们经常使用到了Iterator(迭代器)。使用迭代器,你不需要干涉其遍历的过程,只需要每次取出一个你想要的数据进行处理就可以了。
但是在使用的时候也是有不同的。List和Set都有iterator()来取得其迭代器。对List来说,你也可以通过listIterator()取得其迭代器,两种迭代器在有些时候是不能通用的,Iterator和ListIterator主要区别在以下方面:
-
ListIterator有add()方法,可以向List中添加对象,而Iterator不能
-
ListIterator和Iterator都有hasNext()和next()方法,可以实现顺序向后遍历,但是ListIterator有hasPrevious()和previous()方法,可以实现逆向(顺序向前)遍历。Iterator就不可以。
-
ListIterator可以定位当前的索引位置,nextIndex()和previousIndex()可以实现。Iterator没有此功能。
-
都可实现删除对象,但是ListIterator可以实现对象的修改,set()方法可以实现。Iierator仅能遍历,不能修改。
因为ListIterator的这些功能,可以实现对LinkedList等List数据结构的操作。其实,数组对象也可以用迭代器来实现。 ListIterator 其实就是 对 Iterator 功能的扩展
linkedlist--->类图
ListIterator 结构
Iterator 结构
AbstractList 集合中的Itr 和ListItr 实现类源码
Iterator 接口的实现类Itr
private class Itr implements Iterator<E> {
/**元素的下标
* Index of element to be returned by subsequent call to next.
*/
int cursor = 0;
/**上一个元素的下标。如果元素已被删除就设置为-1
* Index of element returned by most recent call to next or
* previous. Reset to -1 if this element is deleted by a call
* to remove.
*/
int lastRet = -1;
/**允许修改的次数,违规操作会抛异常
* The modCount value that the iterator believes that the backing
* List should have. If this expectation is violated, the iterator
* has detected concurrent modification.
*/
int expectedModCount = modCount;
/*检查是否还有下一个元素*/
public boolean hasNext() {
return cursor != size();
}
/*光标下移,并且返回当前的元素*/
public E next() {
checkForComodification();
try {
int i = cursor;
E next = get(i);
lastRet = i;
cursor = i + 1;
return next;
} catch (IndexOutOfBoundsException e) {
checkForComodification();
throw new NoSuchElementException();
}
}
/*移除元素*/
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
AbstractList.this.remove(lastRet);
if (lastRet < cursor)
cursor--;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException e) {
throw new ConcurrentModificationException();
}
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
ListIterator接口的实现类ListItr 继承了Itr 类 然后扩展了自己的方法
private class ListItr extends Itr implements ListIterator<E> {
ListItr(int index)
{
cursor = index;
}
public boolean hasPrevious()
{
return cursor != 0;
}
public E previous()
{
checkForComodification();
try {
int i = cursor - 1;
E previous = get(i);
lastRet = cursor = i;
return previous;
} catch (IndexOutOfBoundsException e) {
checkForComodification();
throw new NoSuchElementException();
}
}
public int nextIndex()
{
return cursor;
}
public int previousIndex()
{
return cursor-1;
}
public void set(E e)
{
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try
{
AbstractList.this.set(lastRet, e);
expectedModCount = modCount;
}
catch (IndexOutOfBoundsException ex)
{
throw new ConcurrentModificationException();
}
}
public void add(E e)
{
checkForComodification();
try
{
int i = cursor;
AbstractList.this.add(i, e);
lastRet = -1;
cursor = i + 1;
expectedModCount = modCount;
}
catch (IndexOutOfBoundsException ex)
{
throw new ConcurrentModificationException();
}
}
}
LinkedList 集合使用迭代器源码分析 使用的是LinkedList 集合中自己封装的方法
LinkedList 集合迭代器源码
public ListIterator<E> listIterator(int index)
{
checkPositionIndex(index);
// 构造方法的时候是0
return new ListItr(index);
}
private class ListItr implements ListIterator<E>
{
// 保存当前正在获取的元素
private Node<E> lastReturned;
// 当前要取到的元素
private Node<E> next;
// 下一个要取元素的下标
private int nextIndex;
// 修改次数
private int expectedModCount = modCount;
ListItr(int index)
{
//创建对象的时候初始化 2个属性
// assert isPositionIndex(index);
// 当前要取到的元素
next = (index == size) ? null : node(index);
// 首次要取到的元素的下表
nextIndex = index;
}
public boolean hasNext()
{
return nextIndex < size;
}
public E next()
{
checkForComodification();
if (!hasNext())
throw new NoSuchElementException();
// 保存当前正在遍历的元素
lastReturned = next;
next = next.next;
nextIndex++;
return lastReturned.item;
}
public boolean hasPrevious() {
return nextIndex > 0;
}
public E previous() {
checkForComodification();
if (!hasPrevious())
throw new NoSuchElementException();
lastReturned = next = (next == null) ? last : next.prev;
nextIndex--;
return lastReturned.item;
}
public int nextIndex() {
return nextIndex;
}
public int previousIndex() {
return nextIndex - 1;
}
public void remove() {
checkForComodification();
if (lastReturned == null)
throw new IllegalStateException();
Node<E> lastNext = lastReturned.next;
unlink(lastReturned);
if (next == lastReturned)
next = lastNext;
else
nextIndex--;
lastReturned = null;
expectedModCount++;
}
public void set(E e) {
if (lastReturned == null)
throw new IllegalStateException();
checkForComodification();
lastReturned.item = e;
}
public void add(E e) {
checkForComodification();
lastReturned = null;
if (next == null)
linkLast(e);
else
linkBefore(e, next);
nextIndex++;
expectedModCount++;
}
public void forEachRemaining(Consumer<? super E> action) {
Objects.requireNonNull(action);
while (modCount == expectedModCount && nextIndex < size) {
action.accept(next.item);
lastReturned = next;
next = next.next;
nextIndex++;
}
checkForComodification();
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
linkedlist 倒序遍历 源码分析
private class DescendingIterator implements Iterator<E>
{
// 元素的个数
private final ListItr itr = new ListItr(size());
public boolean hasNext()
{
// 其实就是调用的ListItr 类的方法
return itr.hasPrevious();
}
public E next()
{
return itr.previous();
}
public void remove()
{
itr.remove();
}
}
linkedList Demo
LinkedList<String> list = new LinkedList();
list.add("1");
list.add("2");
list.add("3");
Iterator<String> it = list.iterator();
while (it.hasNext())
{
String str = it.next();
if (str.equals("111"))
{
it.remove();
}
else
{
System.out.println(str);
}
}
// 其实都是一样的 list.iterator 和 list.listIterator 调用的实现方法都是一样
Iterator<String> itr = list.listIterator();
while (itr.hasNext())
{
System.out.println(itr.next());
itr.remove();
}
Iterator list2 = list.descendingIterator();
while (list2.hasNext())
{
System.out.println(list2.next());
list2.remove();
}