在一个ArrayList中使用两个迭代器

4

编辑:感谢您的及时回复。现在我明白这个任务行不通。从另一个线程中,我了解到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是否也是如此,并且我搜索了很多,但所有结果都只是使用迭代器来打印一些东西。非常感谢您的帮助。


创建第二个迭代器后,它应该指向第一个位置还是第一个迭代器的下一个位置? - Stan Kurilin
正如下面所提到的,这并不是你想要的结果。也许你可以分享一下你想要实现什么,以便找到更好的方法? - Mike Yockey
yock:谢谢。我编辑了帖子以描述我真正想做的事情。 - EXP0
5个回答

8

以下是不应该做的事情:

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循环来获得我想要的结果吗?谢谢。 - EXP0
4
在Java中,当您不想了解底层的集合实现时,可以使用迭代器(Iterator)。从Java 5开始,由于使用Iterable和Iterator来实现for-each循环语法,因此Iterator的使用变得更少(明确地)。在Java 5中,主要是在需要遍历并有条件地删除元素时使用Iterator。 - Dilum Ranatunga
谢谢。如果我想将指针指向下一个对象,我猜应该使用nextIndex()。这会导致任何超出范围的问题吗?在使用nextIndex之前,我需要检查吗?谢谢。 - EXP0
1
不幸的是,如果在第二个while循环中调用bItr.remove(),你会得到ConcurrentModificationException异常,在我的情况下这非常令人沮丧。 - kirhgoff

5

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

ListIterator bIter = list.listIterator(n);

谢谢!我可以问一下如何从第一个迭代器中获取“n”(索引)吗?如果是在C++中,我可以使用“aIter - aList.beginning()”。在Java中我能做到这点吗? - EXP0
请查看ListIterator的Javadoc:http://download.oracle.com/javase/1.5.0/docs/api/java/util/ListIterator.html。有两个方法nextIndex()和previousIndex(),可以给您提供第一个ListIterator的索引。 - anubhava

2

由于您似乎正在使用列表,因此在您的情况下最简单的解决方案是使用两个索引,类似于以下内容:

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

2

这段代码是有效的,但它并不能实现你想要的功能。你仍然只有一个迭代器,外部循环将在内部循环第一次终止后终止。

Java迭代器无法被有意义地复制。你需要使用一个简单的for循环来递增索引。


0
做这个:
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 中...仅进行非结构性更改以保持您的理智。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接