2017-04-20 87 views
0

這是一個示例代碼,尋找一般化的解決方案。如何複製迭代器對象?

List<String> names = new ArrayList<String>(); 
    for(int i=0; i<names.size()-1; i++){ 
     for(int j=i+1; j<names.size(); j++){ 
      if(names.get(i) == names.get(j)) { 
       //return true; 
      } 
     } 
    } 

我想通過增強的for-loop替換上面的for-loop。 因此嘗試過這樣的嘗試。 上述替換for循環迭代通過:

String name; 
    Iterator<String> itr2; 
    Iterator<String> itr1 = names.iterator(); 
    while(itr1.hasNext()) { 
    // for(name=itr1.next(); itr1.hasNext();) { 
     name = itr1.next(); // iterating itr1 
     itr2 = itr1; 
     while(itr2.hasNext()){ 
      if(name.equalsIgnoreCase(itr2.next())) { // iterating itr2 
       return true; 
      } 
     } 
    } 

我們迭代itr2但ITR1也在發生變化。這是因爲確定了itr1 = itr2。是否有可能複製迭代器對象而不是分配? 而不是迭代器任何其他邏輯也歡迎。

謝謝。

+0

也許創建一個新的數組,然後重新分配?你用什麼java版本? – LazerBanana

+0

請注意,您的第二個代碼段不使用增強功能,除此之外,您需要在列表中使用'subList()'。 – Thomas

+2

你爲什麼要更換它?您在第一個代碼中依賴於索引,內部循環基於外部循環的索引。增強的循環或迭代器不提供索引值,所以你只是在沒有的情況下創建一個問題。 – f1sh

回答

1

如果您想使用增強功能,您無法直接訪問迭代器,並且在任何情況下都無法/不應該重新分配迭代器。

相反,嘗試與子列表和一個額外的索引計數器:

List<String> names = Arrays.asList("a", "b", "a", "b", "c"); 

int i = 0; 
for(String n : names.subList(0, names.size() - 1)) { 
    for(String s : names.subList(i + 1, names.size())) { 
    if(n.equals(s)) { 
     return true; 
    } 
    } 

    i++; 
} 

這不是明顯優於原來的版本,只是針對教育目的。有可能有更好的方法來實現你的實際目標。

或者,使用Java 8,你可以利用流:

boolean hasDuplicates = IntStream.range(0, names.size() - 1) 
    .filter(i -> names.subList(i + 1, names.size()).contains(names.get(i))) 
    .findAny() 
    .isPresent(); 
+0

非常感謝你,這就是我正在尋找的東西。我將開始學習java 8. –

+0

請記住,這些示例不會忽略套管。如果套管很重要,你應該把'n.equals(s)'改爲'n.equalsIgnoreCase(s)'。對於Java 8的例子,你應該首先以大寫或小寫轉換列表。 –

0

在一定程度上,複製一個迭代器,你將需要進行新的迭代。所以,最容易做的事情就是

List<String> itor2 = new LinkedList(); 
for(String s : itor) 
    itor2.add(s); 

當然,如果你必須做出一個新的對象反正,和你只是在檢查重複,我反而只是遍歷列表一次,加入到像一本字典HashMap如果我還沒有看到這個值。

0

好像你正試圖找出你是否在列表中有重複項(忽略套管)。您不一定必須使用for循環。如果您正在尋找簡單的truefalse值。您可以:

public boolean hasDuplicatesIgnoreCase(List<String> names) 
{ 
    return names.stream() 
      .map(String::toLowerCase) 
      .distinct() 
      .collect(Collectors.toList()) 
      .size() != names.size(); 
} 

這不是一個答案,你問的問題,但可能是你的問題的解決方案。否則@Thomas使用子列表有最好的答案。

0

好像你想檢查一個列表是否已經有一個名字並且返回true如果存在的話?我不確定這是否正確使用,但我設法以這種方式來達到您要求的效果。

List<String> names = Arrays.asList("a", "b", "c", "d", "a"); 
    final Set<String> set = new HashSet<>(); 

    for (String name: names) { 
     if (!set.add(name)) return true; 
    } 

    return false; 

當一個元素已經被添加,因此試圖這樣做會告訴我們,如果名稱已經存在或不set.add返回false。