Java - ListIterator 和 hasNext

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17099782/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-01 00:58:15  来源:igfitidea点击:

Java - ListIterator and hasNext

javalistiterator

提问by testermaster

I'm studying Java, and I've a problem with ListIterator. I've a List with these characters: b u o n g i o r n o. My code returns "buongiorno", while I was expecting it to print "buongiorn", without the trailing "o". I was expecting this because of the hasNext()function. My code uses recursion. Can you explain to me the reason?

我正在学习 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);
}

回答by darijan

It would be more clear if the list had only one element, lets say "b". hasNext()would actually return true, and next()would read it and the iteration would end after that.

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

Explanation:

解释:

If you call Iterator<Object> it= list.iterator()on any non-empty list (even if it has only one element), you get truefor calling the hasNext(). That is because the iterator is initialized BEFORE the first element:

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

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

And when you call next()it does two things:

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

  • it reads the element in front of the iterator,
  • moves the iterator just after the element that has been just read, and before the next one.
  • 它读取迭代器前面的元素,
  • 将迭代器移动到刚读取的元素之后,下一个元素之前。

In your example - it prints "b" and stops before the "u":

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

  b u n g i o r n o 
   ^
   i

And just before the end:

就在结束之前:

  b u n g i o r n o
                 ^
                 i

It actually has the next value - "o". Calling the next()will read that value and jump after the o. There are no more elements. hasNext()will show false, and calling next()will result in an exception.

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

Technical details:

技术细节:

Basic idea how iterator is implemented is this: - when the Iteratoris created by calling the iterator()on a List, its inner variable called nextis pointing to the first element of the list. - hasNext()just checks whether the nextis != null. - next()returns nextand sets the nextto show the next element.

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

This is java.util.ArrayListIterator (with some details omitted):

这是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];
     }

 }

回答by Ravi Thapliyal

The ListIterator.hasNext()would return truefor the last "o" character as well (just like every other character). Hence, the elsewould get executed too. It's only after the last "o" has been fetched that hasNext()would return false (since it has gone past all the elements now).

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

The thing to note here is that hasNext()only checks if something else is still available for return on the next()call. It doesn't fetch or skip it by itself.

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

回答by Eli Algranti

The iterator starts "pointing" to the item before the first one.

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

next() makes the iterator point to the next item and return it.

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

So you are actually iterating through the whole list.

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

This is to enable the following syntax when iterating:

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

while (it.hasNext())
{
   ItemClass itemValue = it.next();
   // do something with the value
}

an the same syntax can be used even if the iterator is empty.

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

回答by Tom Hawtin - tackline

When the iterator is at the last 'n' and ricCreais called, then hasNextwill return trueand nextwill return 'o'.

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

So you may want to write something like:

所以你可能想写一些类似的东西:

public static String ricCrea(ListIterator<Character> it) {
    if (it.hasNext()) {
        Character c = it.next();
        if (it.hasNext()) {
            return c + ricCrea(it);
        }
    }
    return "";
 }

回答by Mayank Butpori

hasnext() method just lets you know if there is a character left out in the list or not. next() is the method that gets you the value of the character. So, hasnext() doesn't increment the position of the iterator. It just tells whether there is any element in the next position or not, based on which you can call next() or do the desired operation.

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