如何在 Java 中复制迭代器?
我们有一个元素列表,并有一个非常简单的碰撞检测,我们将每个对象与其他对象进行检查。
检查是可交换的,因此为了避免重复两次,我们将在 C++ 中执行此操作:
for (list<Object>::iterator it0 = list.begin(); it0 != list.end(); ++it0)
{
for (list<Object>::iterator it1 = it0; it1 != list.end(); ++it1)
{
Test(*it0, *it1);
}
}
这里的关键位是副本
it1 = it0
您将如何在 Java 中编写此操作?
We have a list of elements and have a very simplistic collision detection where we check every object against every other object.
The check is commutative, so to avoid repeating it twice, we would do this in C++:
for (list<Object>::iterator it0 = list.begin(); it0 != list.end(); ++it0)
{
for (list<Object>::iterator it1 = it0; it1 != list.end(); ++it1)
{
Test(*it0, *it1);
}
}
The key bit here is the copy
it1 = it0
How would you write this in Java?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可以使用 ListIterator 来完成此操作:
但是,对于链接列表(索引访问速度较慢),list.listIterator(index) 仍然需要迭代到正确的位置。
但这样它只是 O(n²) (而且你不能比这更好),而不是像其他答案中的索引访问那样 O(n³) 。 (如果您首先将列表复制到数组中,您可能会更快,但这只是一个常数因子。)
当然,如果您通常需要基于索引的访问(或此迭代器克隆),您最好使用基于数组的列表(或其迭代器支持克隆的自定义列表)。
You can do this with ListIterator:
For a linked list (which has slow index access) the
list.listIterator(index)
still needs to iterate to the right place, though.But this way it is only O(n²) (and you can't get better than this) instead of O(n³) like the index-access in the other answers then. (You might be even faster if you copy your list first to an array, but it is only a constant factor here.)
Of course, if you usually need index-based access (or this iterator-cloning), you would better use an array-based list (or a custom list whose iterator supports cloning).
您无法复制 Java 迭代器,因此您必须在没有它们的情况下执行此操作:
You cannot copy Java iterators, so you'll have to do it without them:
对于链表(索引访问速度较慢),我认为有一种方法可以做到这一点,而不会导致 Paŭlo 提到的 O(n²) 减速。只要不关心列表的访问顺序,就可以从最后一个元素开始外循环并向后迭代,从第一个元素开始内循环并向前迭代,直到两个迭代器相遇。请参阅下面代码中的
iterRevIterator
。对list.listIterator(list.size())
的调用速度很快,因为list
是一个LinkedList
,即双向链表,并且访问最后一个元素不需要遍历列表。差异并不大……
但仍然很重要。
For a linked list (which has slow index access), I think there is a way to do it without incurring in the O(n²) slowdown that Paŭlo mentioned. As long as you don't care about the order the list is visited, you can start the outer loop from the last element and iterate back, and start the inner loop from the first element and iterate forward until the two iterators meet. See
iterRevIterator
in the code below. The call tolist.listIterator(list.size())
is fast becauselist
is aLinkedList
, i.e. a doubly-linked list, and accessing the last element does not require iterating through the list.The difference is not enormous...
but still significant.