5

我正在学习 Java,但遇到了ListIterator. 我有一个包含这些字符的列表:buongiorn o。我的代码返回“buongiorno”,而我希望它打印“buongiorn”,而没有尾随的“o”。由于hasNext()功能,我期待这一点。我的代码使用递归。你能给我解释一下原因吗?

public static String creaStringa(List<Character> lista) {
    System.out.println(lista.size());
    ListIterator<Character> it = lista.listIterator();
    return ricCrea(it);
}


public static String ricCrea(ListIterator<Character> it) {
    if(!(it.hasNext())) {
        return "";
    else
        return String.valueOf(it.next()) +ricCrea(it);
}
4

5 回答 5

8

如果列表只有一个元素会更清楚,比如说“b”。hasNext()实际上会返回 true,并next()会读取它,然后迭代将结束。

解释:

如果你调用Iterator<Object> it= list.iterator()任何非空列表(即使它只有一个元素),你会得到true调用hasNext(). 这是因为迭代器在第一个元素之前被初始化:

  b u n g i o r n o
 ^
 i - iterator

当你调用next()它时,它会做两件事:

  • 它读取迭代器前面的元素,
  • 将迭代器移动到刚刚读取的元素之后,下一个元素之前。

在您的示例中 - 它打印“b”并在“u”之前停止:

  b u n g i o r n o 
   ^
   i

就在结束之前:

  b u n g i o r n o
                 ^
                 i

它实际上具有下一个值 - “o”。调用next()将读取该值并在o. 没有更多的元素。hasNext()将显示为 false,调用next()将导致异常。

技术细节:

实现迭代器的基本思路是这样的: - 当Iterator通过调用iterator()on 创建 aList时,其内部变量被调用next指向列表的第一个元素。-hasNext()只是检查是否next!= null. -next()返回next并设置next以显示下一个元素。

这是java.util.ArrayList迭代器(省略了一些细节):

public Iterator<E> iterator() {
     return new Itr();
}

private class Itr implements Iterator<E> {
     int cursor;       // index of next element to return
     int lastRet = -1; // index of last element returned; -1 if no such
     int expectedModCount = modCount;

     public boolean hasNext() {
         return cursor != size;
     }

     public E next() {
         checkForComodification();
         int i = cursor;
         Object[] elementData = ArrayList.this.elementData;
         cursor = i + 1;
         return (E) elementData[lastRet = i];
     }

 }
于 2013-06-14T01:46:53.013 回答
1

最后一个“o ”字符ListIterator.hasNext()也会返回true(就像其他所有字符一样)。因此,else也会被执行。只有在获取最后一个“o”之后hasNext()才会返回 false(因为它现在已经超过了所有元素)。

这里要注意的是,hasNext()只检查是否还有其他东西可以在next()通话中返回。它不会自行获取或跳过它。

于 2013-06-14T01:35:48.833 回答
1

迭代器开始“指向”第一个之前的项目。

next() 使迭代器指向下一项并返回它。

所以你实际上是在遍历整个列表。

这是为了在迭代时启用以下语法:

而 (it.hasNext())
{
   ItemClass itemValue = it.next();
   // 对值做一些事情
}

即使迭代器为空,也可以使用相同的语法。

于 2013-06-14T01:36:48.723 回答
0

haveext() 方法只是让您知道列表中是否有字符遗漏。next() 是获取字符值的方法。因此,haveext() 不会增加迭代器的位置。它只是告诉下一个位置是否有任何元素,您可以根据它调用 next() 或执行所需的操作。

于 2013-06-14T02:27:16.683 回答
0

当迭代器位于最后一个'n'并被ricCrea调用时,然后hasNext将返回truenext返回'o'。

所以你可能想写这样的东西:

public static String ricCrea(ListIterator<Character> it) {
    if (it.hasNext()) {
        Character c = it.next();
        if (it.hasNext()) {
            return c + ricCrea(it);
        }
    }
    return "";
 }
于 2013-06-14T01:35:13.013 回答