【问题标题】:using two iterators in one ArrayList在一个 ArrayList 中使用两个迭代器
【发布时间】:2011-09-01 21:01:39
【问题描述】:

编辑:感谢您的所有及时回复。现在我看到任务不会工作。从另一个线程中,我读到 Java 中的迭代器远不如 C++ 中的迭代器强大。那请问为什么在Java中使用迭代器?只是为了替换“for”循环?谢谢。

一些注意事项:

  • 第二个迭代器应该从第一个迭代器后面的位置开始。
  • 我尝试从头开始遍历有序列表,在列表中找到一些与 aItr 所指向的具有相似属性的对象。

我不介意使用两个“for”循环,但我知道 Java 对所有这些库都非常强大。我只是好奇是否有比两个“for”循环更好的方法。谢谢。

嗨,

我一直在使用 C++,但我是 Java 新手,所以请多多包涵。我尝试使用两个迭代器循环遍历 ArrayList。第一个迭代器遍历列表,第二个迭代器从第一个迭代器指向的位置开始,一直到列表的末尾。以下代码是我想要做的(虽然可能无效):

.......; //initialize aList here ......
Iterator aItr = aList.iterator();
while(aItr.hasNext()){
     int a = aItr.next();
     Iterator bItr = aItr; //-----> is it valid? Any bad consequence?
     while (bItr.hasNext()){
         ............; //do stuff
     }
}

将一个迭代器分配给另一个迭代器是否有效?如果不是,那么做我想做的最好的方法是什么?谢谢。

我知道它在 C++ 中有效,但不确定 Java,我搜索了很多,但所有结果都使用迭代器来打印一些东西。非常感谢您的帮助。

【问题讨论】:

  • 第二个迭代器在创建后应该指向哪里——在第一个位置还是在第一个点位置之后?
  • 正如下面提到的,这不会做你想做的事。也许您可以分享您的目标,以便找到更好的方法?
  • yock:谢谢。我编辑帖子以描述我真正想做的事情。

标签: java iterator


【解决方案1】:

你不应该这样做:

Iterator bIter = aIter;

因为Java中没有复制构造函数等; bIter 将是对相同底层迭代器的引用。

可以以这种方式使用 ListIterator:

ListIterator aItr = aList.listIterator();
while (aItr.hasNext()) {
 int a = aItr.next();
 ListIterator bItr = aList.listIterator(aItr.previousIndex());
 while (bItr.hasNext()) {
   // ...
 }
}

但是如果你认为 ListIterator 应该有一个 copy() 方法或类似的东西,我同意你的看法......

【讨论】:

  • 谢谢!你说的对。我没有在 Java 中找到迭代器的复制构造函数。这就是为什么我很困惑,因为它限制了迭代器的使用。那么在Java中,人们使用迭代器只是为了替换for循环吗?我应该只使用两个 for 循环来获得我想要的吗?谢谢。
  • 在 Java 中,当您不想了解底层 Collection 实现时,可以使用 Iterator。从 Java 5 开始,由于 for-each 结构在下面使用 Iterable 和 Iterator,Iterator 的使用较少(显式)。在 Java 5 中,Iterator 主要用于迭代和有条件地删除元素。
  • 谢谢。如果我想将 bItr 指向下一个对象,我猜应该使用 nextIndex()。这会导致任何超出范围的问题吗?在使用 nextIndex 之前是否需要检查?谢谢。
  • 不幸的是,如果在第二次调用 bItr.remove() 时,您将收到 ConcurrentModificationException,在我的情况下,这非常可悲。
【解决方案2】:

如果您想在列表中的第 n 个位置使用第二个列表迭代器,请使用 List#listIterator(int index):

ListIterator bIter = list.listIterator(n);

【讨论】:

  • 谢谢!请问如何从第一个迭代器中获取“n”(索引)?如果它在 C++ 中,我可以使用“aIter - aList.beginning()”。那是我可以用 Java 做的吗?
  • 请查看 ListIterator 的 Javadoc:download.oracle.com/javase/1.5.0/docs/api/java/util/… 有 2 个方法 nextIndex() 和 previousIndex() 可以为您提供第一个 ListIterator 的索引。
【解决方案3】:

由于您似乎在使用列表,因此在您的情况下最简单的解决方案是使用两个索引,如下所示:

for (int i = 0; i < aList.size(); i++) {
  for (int j = i; j < aList.size(); j++) {
    // do stuff with aList's elements
    aList.get(j);
  }
}

使用迭代器,你可以实现类似的事情,但你必须为内部循环构造新的迭代器,可能来自

aList.subList(i, aList.size()).iterator();

【讨论】:

    【解决方案4】:

    它是有效的,但它不会做你想让它做的事情。您仍然只有一个迭代器,并且外部循环将在内部循环第一次终止后终止。

    Java 迭代器不能被有意义地复制。您必须使用一个简单的 for 循环来增加索引。

    【讨论】:

      【解决方案5】:

      这样做:

      ArrayList<String> aList = new ArrayList<String>();
      // do something to fill the list
      for (int i = 0; i < aList.size(); i++)
      {
        ArrayList<String> bList = aList.subList(i, aList.size());
        for (int j = 0; j < bList.size(); j++)
        {
          // do stuff with the sublist
        }
      }
      

      请务必注意,bList 由 aList 支持,因此对 bList 的更改将反映在 aList 中...进行非结构性更改只是为了保持理智。

      【讨论】:

        猜你喜欢
        • 2010-11-25
        • 2021-10-05
        • 1970-01-01
        • 2021-11-21
        • 2016-03-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多