简体   繁体   English

如何引用迭代器中的当前对象

[英]How do I refer to the current object in an iterator

I am trying to implement a search method in a TreeSet. 我试图在TreeSet中实现一个搜索方法。 By using an iterator with a condtional I would like to be able to run through the set and print the object that matches the condition. 通过使用带有condtional的迭代器,我希望能够遍历集合并打印匹配条件的对象。 However the way I am doing it at the moment is printing out the subsequent object rather than the current. 然而,我现在这样做的方式是打印出后续对象而不是当前对象。 This is what I have so far: 这是我到目前为止:

public void getDetails() {
        Iterator<Person> it = this.getPersonSet().iterator();
        System.out.println("Enter First Name");
        String first = in.next().toLowerCase();
        System.out.println("Enter Second Name");
        String last = in.next().toLowerCase();

        while (it.hasNext()) {
            if (it.next().getLast().toLowerCase().equals(last)) {
                Person p = it.next();
                System.out.println(p);
            }
        }

    }

Any help would be great 任何帮助都会很棒

This is what you would want to do: 这是你想要做的:

while (it.hasNext()) {
            Person p = it.next();
            if (p.getLast().toLowerCase().equals(last)) {
                System.out.println(p);
            }
        }

How do I refer to the current object in an iterator 如何引用迭代器中的当前对象

For the record, the Iterator API does not allow you to do this. 对于记录, Iterator API不允许您这样做。 There is no notion of a "current" object. 没有“当前”对象的概念。 The Iterator.next() method gives you the next object ... and moves on. Iterator.next()方法为您提供下一个对象...并继续前进。

(The ListIterator.previous() and ListIterator.next() methods are analogous. Note that in the ListIterator case, method behaviour is documented in terms of a cursor that denotes a position before / between / after elements in the sequence being iterated.) ListIterator.previous()ListIterator.next()方法是类似的。请注意,在ListIterator情况下,方法行为是根据游标来记录的,该游标表示迭代序列中元素之前/之间/之后的位置。)

The solution is to assign the result of calling it.next() to a temporary variable, as described by the accepted answer. 解决方案是将调用it.next()的结果分配给临时变量,如接受的答案所述。


I don't know for sure why the designers didn't include the notion of a "current" object in the API, but I can think of a couple of reasons: 我不确定为什么设计师没有在API中包含“当前”对象的概念,但我可以想到几个原因:

  • It would make a typical iterator object bigger; 它会使典型的迭代器对象更大; ie an extra field to hold the current object. 即一个额外的字段来保存当前对象。
  • It would mean more 1 more method for an Iterator class to implement. 这意味着要为Iterator类实现更多的方法。
  • The notion of a current object does not fit well with the "cursor" model documented in the ListIterator interface ... and implied by the current Iterator design. 当前对象的概念不适合ListIterator接口中记录的“游标”模型......并且由当前的Iterator设计暗示。
  • There is a minor issue of the Iterator "hanging onto" the current object, thereby preventing it from being GC'ed. 迭代器“挂在”当前对象上有一个小问题,从而阻止它被GC控制。
  • The large majority of iterator use-cases don't require a current object. 绝大多数迭代器用例不需要当前对象。
  • There are other ways to deal with this. 还有其他方法可以解决这个问题。

Sounds like a good call ... 听起来很不错......

If you need an existing implementation, you can use the ones from Google Guava or Apache Commons Collections . 如果您需要现有的实现,可以使用Google GuavaApache Commons Collections中的实现
The other answers are easier for your simple problem, but if you need to pass the iterator around and keep track of the last item returned by next(), these would help. 其他答案对于您的简单问题更容易,但如果您需要传递迭代器并跟踪next()返回的最后一项,这些将有所帮助。

Here is an example using Guava with the OP's code (assumging Person indeed has a String toLowerCase() method): 下面是一个使用Guava和OP代码的例子(假设Person确实有一个String toLowerCase()方法):

import com.google.common.collect.PeekingIterator;
import static com.google.common.collect.Iterators.peekingIterator;

public void getDetails() {
    PeekingIterator<Person> it = peekingIterator(this.getPersonSet().iterator());
    System.out.println("Enter First Name");
    String first = in.next().toLowerCase();
    System.out.println("Enter Second Name");
    String last = in.next().toLowerCase();

    while (it.hasNext()) {
        // note the usage of peek() instead of next()
        if (it.peek().getLast().toLowerCase().equals(last)) {
            Person p = it.next();
            System.out.println(p);
        }
    }

}

Hold the reference of the object in a separate var: 在单独的var中保持对象的引用:

Person current = it.next();
current.methodOne();
current.methodTwo();

When you're done with the current value, re-assing it the next 完成当前值后,再次对其进行重新分配

...
// done? 
current = it.next();

In a loop looks like: 在循环中看起来像:

while( it.hasNext() ) { 
   Person current = it.next();
   current.doA();
   current.doB();
   current.doC();
 }

the next() method returns the current object, like this: next()方法返回当前对象,如下所示:

private class IterSinglyLinked implements SimpleIterator<T> {
    Element curr = head;        // next element to return

    public boolean hasNext() {
        return curr != null;
    }

    public T next() throws Exception {
        if (curr == null) throw new Exception("no more elements");
        T data = curr.data;
        curr = curr.next;
        return data;
    }
}

If it returns the next one rather than the current one, there will be no way to reach the very first one 如果它返回下一个而不是当前的那个,则无法到达第一个

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM