java Java中的String类为什么不实现Iterable?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2772511/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why doesn't the String class in Java implement Iterable?
提问by user333335
Many Java framework classes implement Iterable, however Stringdoes not. It makes sense to iterate over characters in a String, just as one can iterate over items in a regular array.
许多 Java 框架类实现了Iterable,但String没有实现。迭代 a 中的字符是有意义的String,就像可以迭代常规数组中的项目一样。
Is there a reason why Stringdoes not implement Iterable?
有String没有不执行的原因Iterable?
采纳答案by Vivin Paliath
There really isn't a good answer. An iterator in Java specifically applies to a collection of discrete items (objects). You would think that a String, which implements CharSequence, should be a "collection" of discrete characters. Instead, it is treated as a single entity that happens to consist of characters.
真的没有很好的答案。Java 中的迭代器专门应用于离散项(对象)的集合。你可能会认为,一个String,它实现了CharSequence,应该是一个离散字符“收藏”。相反,它被视为碰巧由字符组成的单个实体。
In Java, it seems that iterators are only really applied to collections and not to a string. There is no reason why it is this way (near as I can tell - you would probably have to talk to Gosling or the API writers); it appears to be convention or a design decision. Indeed, there is nothing preventingCharSequencefrom implementing Iterable.
在 Java 中,迭代器似乎只真正应用于集合而不是字符串。没有理由这样(据我所知 - 您可能需要与 Gosling 或 API 编写者交谈);这似乎是惯例或设计决定。事实上,没有什么可以阻止CharSequence实现Iterable.
That said, you can iterate over the characters in a string like so:
也就是说,您可以像这样迭代字符串中的字符:
for (int i = 0; i < str.length(); i++) {
System.out.println(str.charAt(i));
}
Or:
或者:
for(char c : str.toCharArray()) {
System.out.println(c);
}
Or:
或者:
"Java 8".chars().forEach(System.out::println);
Also note that you cannot modify a character of a String in place because Strings are immutable. The mutable companion to a String is StringBuilder (or the older StringBuffer).
另请注意,您不能就地修改字符串的字符,因为字符串是不可变的。String 的可变伴侣是 StringBuilder(或较旧的 StringBuffer)。
EDIT
编辑
To clarify based on the comments on this answer. I'm trying to explain a possible rationaleas to why there is no Iterator on a String. I'm not trying to say that it's not possible; indeed I think it would make sense for CharSequenceto implement Iterable.
根据对此答案的评论进行澄清。我试图解释一个可能的理由,说明为什么String. 我并不是想说这是不可能的;事实上,我认为CharSequence实施Iterable.
Stringprovides CharSequence, which, if only conceptually, is different from a String. A Stringis usually thought of as a single entity, whereas CharSequenceis exactly that: a sequence of characters. It would make sense to have an iterator on a sequence of characters (i.e., on CharSequence), but not simply on a Stringitself.
String提供CharSequence,如果只是在概念上,它与 a 不同String。AString通常被认为是一个单一的实体,而CharSequence恰恰是:一个字符序列。在字符序列(即 on CharSequence)上有一个迭代器是有意义的,但不仅仅是在 aString本身上。
As Foxfire has rightly pointed out in the comments, Stringimplements the CharSequenceinterface, so type-wise, a Stringis a CharSequence. Semantically, it seems to me that they are two separate things - I'm probably being pedantic here, but when I think of a StringI usually think of it as a single entity that happens to consist of characters. Consider the difference between the sequence of digits 1, 2, 3, 4and the number 1234. Now consider the difference between the string abcdand the sequence of characters a, b, c, d. I'm trying to point out this difference.
正如 Foxfire 在评论中正确指出的那样,String实现了CharSequence接口,因此在类型方面, aString是 a CharSequence。从语义上讲,在我看来,它们是两个独立的东西——我在这里可能是迂腐,但是当我想到 a 时,String我通常认为它是一个碰巧由字符组成的单一实体。考虑的数字序列之间的差异1, 2, 3, 4和数量1234。现在考虑字符串abcd和字符序列之间的区别a, b, c, d。我试图指出这种差异。
In my opinion, asking why Stringdoesn't have an iterator is like asking why Integerdoesn't have an iterator so that you can iterate over the individual digits.
在我看来,问为什么String没有迭代器就像问为什么Integer没有迭代器那样你可以迭代单个数字。
回答by Foxfire
The reason is simple: The string class is much older than Iterable.
原因很简单:字符串类比 Iterable 古老得多。
And obviously nobody ever wanted to add the interface to String (which is somewhat strange because it does implement CharSequence which is based on exactly the same idea).
显然没有人想将接口添加到 String (这有点奇怪,因为它确实实现了基于完全相同的想法的 CharSequence )。
However it would be somewhat imperformant because Iterable returns an object. So it would have to Wrap every Char returned.
然而,它会有些低效,因为 Iterable 返回一个 object。所以它必须包装每个返回的字符。
Edit: Just as comparison: .Net does support enumerating on String, however in .Net Iterable also works on native types so there is no wrapping required as it would be required in Java.
编辑:就像比较:.Net 确实支持枚举字符串,但是在 .Net 中 Iterable 也适用于本机类型,因此不需要像在 Java 中那样需要包装。
回答by Kevin Bourrillion
For what it's worth, my coworker Josh Bloch strongly wishes to add this feature to Java 7:
无论如何,我的同事 Josh Bloch 强烈希望将此功能添加到 Java 7:
for (char c : aString) { ... }
for (char c : aString) { ... }
and
和
for (int codePoint : aString) { ... }
for (int codePoint : aString) { ... }
This would be the easiest way to loop over chars and over logical characters (code points) ever. It wouldn't require making Stringimplement Iterable, which would force boxing to happen.
这将是循环遍历字符和逻辑字符(代码点)的最简单方法。它不需要制作String工具Iterable,这会强制拳击发生。
Without that language feature, there's not going to be a really good answer to this problem. And he seems very optimistic that he can get this to happen, but I'm not sure.
如果没有那个语言特性,这个问题就不会有真正好的答案。他似乎非常乐观地认为他可以做到这一点,但我不确定。
回答by akuhn
They simply forgot to do so.
他们只是忘了这样做。
回答by Hallvard Tr?tteberg
One of the main reasons for making String implement Iterable is to enable the simple for(each) loop, as mentioned above. So, a reason for not making String implement Iterable could be the inherent inefficiency of a na?ve implementation, since it requires boxing the result. However, if the implementation of the resulting Iterator (as returned by String.iterator()) is final, the compiler could special-case it and generate byte-code free from boxing/unboxing.
使 String 实现 Iterable 的主要原因之一是启用简单的 for(each) 循环,如上所述。因此,不让 String 实现 Iterable 的一个原因可能是简单实现的内在效率低下,因为它需要对结果进行装箱。但是,如果生成的迭代器(由 String.iterator() 返回)的实现是最终的,编译器可以对它进行特殊处理并生成没有装箱/拆箱的字节码。
回答by medopal
If you are really instrested in iterating here:
如果你真的很想在这里迭代:
String str = "StackOverflow";
for (char c: str.toCharArray()){
//here you go
}
回答by Tom Hawtin - tackline
Iterableof what? Iterable<Integer>would make most sense, where each element represents a Unicode codepoint. Even Iterable<Character>would be slow and pointless when we have toCharArray.
Iterable什么?Iterable<Integer>最有意义,其中每个元素代表一个 Unicode 代码点。Iterable<Character>当我们有时,即使是缓慢而毫无意义的toCharArray。

