2011-03-02 116 views
18

我正試圖在TreeSet中實現搜索方法。通過使用帶有條件的迭代器,我希望能夠遍歷集合並打印與條件匹配的對象。但是我現在正在做的事情是打印出後續的對象而不是當前的對象。 這是我到目前爲止有:如何在迭代器中引用當前對象

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); 
      } 
     } 

    } 

任何幫助將是巨大的

回答

24

這是你想要做什麼:

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

非常感謝,當場:) – Robairto 2011-03-02 01:34:56

+0

這樣不是會跳過ArrayList中的第一個對象? :/ – 2017-02-11 11:23:53

+1

@SrujanBarai - nope。 (字面意思是......它會「不跳過它」) – 2017-03-30 01:32:48

1

保持在一個單獨的對象的引用var:

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

當您完成當前值後,重新分配下一個

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

在循環中的樣子:

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

如何我指的是當前對象的迭代器

根據記錄,該Iterator API不允許你去做這個。沒有「當前」對象的概念。 Iterator.next()方法爲您提供下一個對象...並繼續。

(該ListIterator.previous()ListIterator.next()方法是類似的。注意,在ListIterator情況下,方法的行爲是在表示位置的光標方面記載前/間/後的序列中的元素被重複。)

解決方法是將調用it.next()的結果分配給臨時變量,如接受的答案所述。


我不知道知道爲什麼設計師沒有包括API在「當前」對象的概念,但我能想到幾個原因:

  • 它會使一個典型的迭代器對象更大;即用於保存當前對象的額外字段。
  • 這意味着更多的Iterator類實現更多的方法。
  • 當前對象的概念不會在ListIterator界面記錄的「光標」模型十分吻合......和當前Iterator設計暗示。
  • Iterator存在一個小問題,「掛在」當前對象,從而阻止它被GC化。
  • 大多數迭代器用例不需要當前對象。
  • 還有其他方法可以解決這個問題。

聽起來像一個良好的通話...

+0

我完全不理解爲什麼沒有「最新」。這種情況的一個非常基本的用法是任何一個想要異步比較當前值和下一個值的情況。例如,如果列表被修改,索引可能不再指向你想要的位置,所以顯而易見的解決方案是一個迭代器,儘管這不允許比較值。爾格。 – Thumbz 2014-03-25 23:28:47

+0

@Thumbz - 恩......看到我的答案,爲什麼「當前」總的來說不好。 (爲了方便其他人,打破一些用例是不好的)。對於你的用例,考慮編寫一個迭代器包裝類,它增加了一個getCurrent()方法......如果這樣可以爲你簡化事情。 – 2014-03-26 00:03:35

+3

如果你看看迭代器的源代碼,你的答案的第二部分沒有任何事情是真的。 迭代器包含2個變量:指向下一個元素的「int cursor」和指向返回的最後一個元素的int lastRet。因此不需要額外的字段。 這些是索引號,而不是對象本身,因此迭代器不會「掛在」當前對象上。 遊標模型用於解釋迭代器的設計,而不是相反。並不是因爲90%不會使用它,您不必實施它。這只是糟糕的設計。 – Didii 2014-07-18 15:11:15

0

如果您需要現有的實施方案,您可以使用Google GuavaApache Commons Collections中的那些。
對於簡單的問題,其他答案更容易,但是如果您需要傳遞迭代器並跟蹤next()返回的最後一個項目,這些將有所幫助。

下面是使用番石榴與OP的代碼示例(assumging 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); 
     } 
    } 

} 
+0

最好是展示一個小例子,說明如何在這個特定情況下使用這些迭代器,而不是簡單地鏈接到它們。 – 2017-01-31 22:24:02