java中的foreach循环可以逆序执行吗?
我需要使用 Java 以相反的顺序运行列表。
那么它转发到哪里:
for(String string: stringList){
//...do something
}
是否有某种方法可以使用 foreach 语法以相反的顺序迭代 stringList?
为了清楚起见:我知道如何以相反的顺序迭代列表,但想知道(出于好奇)如何以 foreach 样式执行此操作。
I need to run through a List in reverse order using Java.
So where this does it forwards:
for(String string: stringList){
//...do something
}
Is there some way to iterate the stringList in reverse order using the for each syntax?
For clarity: I know how to iterate a list in reverse order but would like to know (for curiosity's sake ) how to do it in the for each style.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(16)
Collections.reverse 方法实际上返回一个新列表,其中原始列表的元素以相反的顺序复制到其中,因此相对于原始列表的大小,这具有 O(n) 性能。
作为更有效的解决方案,您可以编写一个装饰器,将 List 的反向视图呈现为 Iterable。 装饰器返回的迭代器将使用装饰列表的 ListIterator 以相反的顺序遍历元素。
例如:
你会这样使用它:
The Collections.reverse method actually returns a new list with the elements of the original list copied into it in reverse order, so this has O(n) performance with regards to the size of the original list.
As a more efficient solution, you could write a decorator that presents a reversed view of a List as an Iterable. The iterator returned by your decorator would use the ListIterator of the decorated list to walk over the elements in reverse order.
For example:
And you would use it like:
如需列表,您可以使用 Google Guava Library:
请注意
Lists.reverse
不会反转整个集合,或者做类似的事情 - 它只允许以相反的顺序进行迭代和随机访问。 这比先逆向收集效率更高。要反转任意可迭代对象,您必须读取全部内容,然后向后“重播”它。
(如果您尚未使用它,我强烈建议您查看番石榴。这是很棒的东西。)
For a list, you could use the Google Guava Library:
Note that
Lists.reverse
doesn't reverse the whole collection, or do anything like it - it just allows iteration and random access, in the reverse order. This is more efficient than reversing the collection first.To reverse an arbitrary iterable, you'd have to read it all and then "replay" it backwards.
(If you're not already using it, I'd thoroughly recommend you have a look at the Guava. It's great stuff.)
List(与 Set 不同)是一个有序集合,对其进行迭代确实会按约定保留顺序。 我本来期望堆栈以相反的顺序迭代,但不幸的是它没有。 所以我能想到的最简单的解决方案是:
我意识到这不是“foreach”循环解决方案。 我宁愿使用 for 循环,也不愿引入像 Google Collections 这样的新库。
Collections.reverse() 也可以完成这项工作,但它会更新列表,而不是以相反的顺序返回副本。
The List (unlike the Set) is an ordered collection and iterating over it does preserve the order by contract. I would have expected a Stack to iterate in the reverse order but unfortunately it doesn't. So the simplest solution I can think of is this:
I realize that this is not a "for each" loop solution. I'd rather use the for loop than introducing a new library like the Google Collections.
Collections.reverse() also does the job but it updates the list as opposed to returning a copy in reverse order.
这会扰乱原始列表,并且还需要在循环之外调用。
另外,您不想每次循环时都执行反向操作 - 如果应用了
Iterables.reverse 想法
之一,情况会是这样吗?This will mess with the original list and also needs to be called outside of the loop.
Also you don't want to perform a reverse every time you loop - would that be true if one of the
Iterables.reverse ideas
was applied?AFAIK 标准库中没有标准的“reverse_iterator”之类的东西支持 for-each 语法,这已经是他们后期引入该语言的语法糖。
您可以执行类似 for(Item element: myList.clone().reverse()) 的操作并支付相关价格。
这似乎也与不为您提供执行昂贵操作的便捷方法的明显现象相当一致 - 因为根据定义,列表可能具有 O(N) 随机访问复杂度(您可以使用单链接实现接口),相反迭代最终可能是 O(N^2)。 当然,如果你有一个ArrayList,你就不需要付出这个代价。
AFAIK there isn't a standard "reverse_iterator" sort of thing in the standard library that supports the for-each syntax which is already a syntactic sugar they brought late into the language.
You could do something like for(Item element: myList.clone().reverse()) and pay the associated price.
This also seems fairly consistent with the apparent phenomenon of not giving you convenient ways to do expensive operations - since a list, by definition, could have O(N) random access complexity (you could implement the interface with a single-link), reverse iteration could end up being O(N^2). Of course, if you have an ArrayList, you don't pay that price.
截至评论:您应该能够使用 Apache Commons
ReverseListIterator
作为 @rogerdpack 说,您需要将
ReverseListIterator
包装为可迭代
。作为 Roland Nordborg-Løvstad 在评论中推荐,您可以在当前的 Java 中使用 Lambdas 进行简化
As of the comment: You should be able to use Apache Commons
ReverseListIterator
As @rogerdpack said, you need to wrap the
ReverseListIterator
as anIterable
.As recommended by Roland Nordborg-Løvstad in the comments, you can simplify with Lambdas in current Java
这可能是一个选择。 希望有一种更好的方法从最后一个元素开始而不是 while 循环到最后。
This may be an option. Hope there is a better way to start from last element than to while loop to the end.
解决方法:
或者使用 guava :
A work Around :
Or with guava :
从 Java 21 开始,
reversed()
方法可用于返回列表上的反向视图,然后可以使用增强的for
对其进行迭代陈述:Starting with Java 21, the
reversed()
method can be used to return a reversed view on the list, which can then be iterated over using an enhancedfor
statement:并非没有编写一些自定义代码,这将为您提供一个枚举器,该枚举器将为您反转元素。
您应该能够在 Java 中通过创建 Iterable 的自定义实现来完成此操作,该实现将以相反的顺序返回元素。
然后,您将实例化包装器(或调用方法,您有什么),它将返回 Iterable 实现,该实现反转 foreach 循环中的元素。
Not without writing some custom code which will give you an enumerator which will reverse the elements for you.
You should be able to do it in Java by creating a custom implementation of Iterable which will return the elements in reverse order.
Then, you would instantiate the wrapper (or call the method, what-have-you) which would return the Iterable implementation which reverses the element in the for each loop.
如果您想使用开箱即用的 foreach 语法并按相反的顺序进行操作,则需要反转集合。
You'd need to reverse your collection if you want to use the for each syntax out of the box and go in reverse order.
上面的所有答案都只能满足要求,要么通过包装另一个方法,要么在外部调用一些外部代码;
以下是从 Thinking in Java 第 4 版第 11.13.1 章 AdapterMethodIdiom 复制的解决方案;
这是代码:
All answers above only fulfill the requirement, either by wrapping another method or calling some foreign code outside;
Here is the solution copied from the Thinking in Java 4th edition, chapter 11.13.1 AdapterMethodIdiom;
Here is the code:
您可以使用 Collections 类反转列表然后循环。
You can use the Collections class to reverse the list then loop.
绝对是这个问题的迟到答案。 一种可能性是在 for 循环中使用 ListIterator。 它不像冒号语法那么干净,但它确实有效。
ListIterator 语法的功劳在于 “在 Java 中迭代列表的方法”
Definitely a late answer to this question. One possibility is to use the ListIterator in a for loop. It's not as clean as colon-syntax, but it works.
Credit for the ListIterator syntax goes to "Ways to iterate over a list in Java"
例如,
现在反转它。
E.g.
Reverse it now.
您可以使用 For-Each 循环以相反的顺序迭代数组,如下所示:
You can iterate through an array in reverse order using For-Each loop like below: