Java 中是否有相当于 Python 的“枚举”功能?功能?
在 Python 中, enumerate
函数允许您进行迭代在一系列(索引,值)对上。例如:
>>> numbers = ["zero", "one", "two"]
>>> for i, s in enumerate(numbers):
... print i, s
...
0 zero
1 one
2 two
在Java中有什么方法可以做到这一点吗?
In Python, the enumerate
function allows you to iterate over a sequence of (index, value) pairs. For example:
>>> numbers = ["zero", "one", "two"]
>>> for i, s in enumerate(numbers):
... print i, s
...
0 zero
1 one
2 two
Is there any way of doing this in Java?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
对于实现
List
的集合接口,可以调用listIterator()
方法获取ListIterator
。迭代器有(除其他外)两种方法 -nextIndex()
,获取索引;和next()
,获取值(与其他迭代器一样)。因此,上面的 Python 的 Java 等价物可能是:
它与 Python 一样,输出:
For collections that implement the
List
interface, you can call thelistIterator()
method to get aListIterator
. The iterator has (amongst others) two methods -nextIndex()
, to get the index; andnext()
, to get the value (like other iterators).So a Java equivalent of the Python above might be:
which, like the Python, outputs:
我发现这与 python 方法最相似。
用法
输出
特性
实现
I find this to be the most similar to the python approach.
Usage
Output
Features
Implementation
严格来说,不可以,因为 Python 中的 enumerate() 函数返回元组列表,而 Java 中不存在元组。
但是,如果您感兴趣的只是打印索引和值,那么您可以遵循 Richard Fearn & 的建议。在迭代器上使用 nextIndex() 和 next()。
另请注意,可以使用更通用的 zip() 函数(使用 Python 语法)来定义 enumerate():
给出 [(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd')]
如果您定义自己的 Tuple 类(请参阅 使用对或Java 中的 2 元组作为起点),那么您当然可以轻松地在 Java 中编写自己的 zip() 函数来使用它(使用链接中定义的 Tuple 类):
一旦您有了 zip (),实现 enumerate() 很简单。
编辑:工作缓慢,所以要结束它:
编辑2:正如对此问题的评论中所指出的,这并不完全等同。虽然它生成与 Python 枚举相同的值,但它的生成方式与 Python 枚举不同。因此,对于大型集合来说,这种方法可能会让人望而却步。
Strictly speaking, no, as the enumerate() function in Python returns a list of tuples, and tuples do not exist in Java.
If however, all you're interested in is printing out an index and a value, then you can follow the suggestion from Richard Fearn & use nextIndex() and next() on an iterator.
Note as well that enumerate() can be defined using the more general zip() function (using Python syntax):
gives [(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd')]
If you define your own Tuple class (see Using Pairs or 2-tuples in Java as a starting point), then you could certainly easily write your own zip() function in Java to make use of it (using the Tuple class defined in the link):
And once you have zip(), implementing enumerate() is trivial.
Edit: slow day at work, so to finish it off:
Edit 2: as pointed out in the comments to this question, this is not entirely equivalent. While it produces the same values as Python's enumerate, it doesn't do so in the same generative fashion that Python's enumerate does. Thus for large collections this approach could be quite prohibitive.
简单直接
示例用法:
Simple and straightforward
Sample usage:
根据Python文档(此处),这是最接近的使用 Java,它不再冗长:
如果您需要使用
List
类...*注意:如果您需要在遍历列表时修改列表,则需要使用 Iterator 对象,因为它能够在不引发 ConcurrentModificationException 的情况下修改列表。
According to the Python docs (here), this is the closest you can get with Java, and it's no more verbose:
If you need to use the
List
class...*NOTE: if you need to modify the list as you're traversing it, you'll need to use the Iterator object, as it has the ability to modify the list without raising a
ConcurrentModificationException
.现在使用 Java 8s Stream API 以及提供
的小型
可以轻松实现。ProtonPack
库StreamUtils第一个示例使用与问题中相同的 for-each 表示法:
尽管没有提供 Python 中的惰性求值。
为此,您必须使用
forEach()
Stream API 方法:可以使用以下无限流来验证延迟计算:
Now with Java 8s Stream API together with the small
ProtonPack
library providingStreamUtils
it can be achieved easily.The first example uses the same for-each notation as in the question:
Above although does not provide the lazy evaluation as in Python.
For that you must use the
forEach()
Stream API method:The lazy evaluation can be verified with the following infinite stream:
不。也许有一些库支持这样的功能。但如果您求助于标准库,那么计算就是您的工作。
No. Maybe there are some libraries for supporting such a functionality. But if you resort to the standard libraries it is your job to count.
我认为这应该是最类似于python“枚举”的java功能,尽管它相当复杂且效率低下。 :将列表的索引映射到其元素即可
基本上,只需使用 ListIterator 或 Collector:或使用 lambda 表达式
:然后您可以将其与增强的 for 循环一起使用:
I think this should be the java functionality that resemble the python "enumerate" most, though it is quite complicated and inefficent. Basically, just map the list's indices to its elements, using ListIterator or Collector:
or using lambda expression:
then you can use it with an enhanced for loop:
通过将泛型与匿名接口相结合,您实际上可以创建一个用于处理枚举的工厂方法。枚举器回调隐藏了下面迭代器的混乱。
结果
扩展思想
Map、Reduce、Filter
我更进一步,基于这个概念创建了 Map、Reduce 和 Filter 函数。
Google 的 Guava 和 Apache common-collections 依赖项包含类似的功能。您可以根据需要查看它们。
By combining generics with anonymous interfaces, you can essentially create a factory method for handing enumeration. The Enumerator callback hides the messiness of the iterator underneath.
Result
Extended Thoughts
Map, Reduce, Filter
I have taken this a step further and created map, reduce, and filter functions based on this concept.
Both Google's Guava and Apache common-collections dependencies include similar functionality. You can check them out as you wish.
使用 Java8 Streams 的语法几乎相同
Pretty much the same syntax using Java8 Streams