How do I apply the for-each loop to every character in a String?
所以我想迭代字符串中的每个字符。
所以我认为:
但是我收到编译错误:
1
| MyClass.java:20: foreach not applicable to expression type |
我怎样才能做到这一点?
在String中每个char的最简单方法是使用toCharArray():
1 2
| for (char ch:"xyz".toCharArray()) {
} |
这为您提供了for-each构造的简洁性,但不幸的是String(这是不可变的)必须执行防御性副本以生成char[](这是可变的),因此存在一些成本损失。
从文档:
[toCharArray() returns] a newly allocated character array whose length is the length of this string and whose contents are initialized to contain the character sequence represented by this string.
有更多冗长的方法来迭代数组中的字符(常规循环,CharacterIterator等),但是如果你愿意支付成本toCharArray() - 每个都是最简洁的。
-
编译器是否会识别出不需要真正的副本并应用适当的优化?
-
顺便说一句,这适用于Java 1.5及以上版本....
-
@Pacerier不,当前的Java编译器永远不会优化代码。
-
@ RAnders00那么,在这种情况下,toCharArray( )被调用3次?
-
@RafiduzzamanSonnet:嗯,不完全是。在评论中他说了一些关于编译器的东西,它是将Java源代码(.java)转换为字节码(.class)的程序。现代JVM(这是运行你的字节码[aka .class和.jar文件])可能能够优化这一点,但我不认为他们会做这样积极的优化,因为这意味着方法调用被省略(这在运行代码中通常是不可取的。
-
如果字符串长度211900000,则完成for (char c : str.toCharArray()) { }所需的时间约为250ms,完成for (char c : charArray) { }所需的时间<10ms。当然,这些时间值将取决于硬件,但重要的是一种方法比另一种方法成本高得多。
-
@RafiduzzamanSonnet:不,toCharArray()不在循环体内;它只被调用一次,然后循环遍历生成的数组。 (for-each循环不同于一般的for -loop,它会在每次迭代时计算停止条件。)
1 2 3 4 5
| String s ="xyz";
for(int i = 0; i < s. length(); i ++)
{
char c = s. charAt(i );
} |
&NBSP;
-
OP期望为循环增强。
-
投票结果是因为这特别不是OP所要求的。虽然这是一个有效的解决方案,但它完全不是被问到的
-
无论OP如何预期,这个性能都比我想象的要好。
您需要使用String类的toCharArray()方法将String对象转换为char数组:
1 2 3 4 5 6 7
| String str ="xyz";
char arr [] = str. toCharArray(); // convert the String object to array of char
// iterate over the array using the for-each loop.
for(char c : arr ){
System. out. println(c );
} |
在Java 8中,我们可以解决它:
1 2
| String str ="xyz";
str. chars(). forEachOrdered(i -> System. out. print((char)i )); |
方法chars()返回doc中提到的IntStream:
Returns a stream of int zero-extending the char values from this
sequence. Any char which maps to a surrogate code point is passed
through uninterpreted. If the sequence is mutated while the stream is
being read, the result is undefined.
为什么要使用forEachOrdered而不是forEach?
forEach的行为明确是非确定性的,其中forEachOrdered对流的每个元素执行操作,如果流具有已定义的遭遇顺序,则按流的遭遇顺序执行操作。所以forEach不保证订单会被保留。另请查看此问题。
我们也可以使用codePoints()进行打印,请参阅此答案以获取更多详细信息。
-
这会创建多个对象,因此,如果没有警告说这可能比简单的索引循环效率低,这个答案就不完整了。
另一个有用的解决方案,您可以使用此字符串作为String数组
如果使用Java 8,则可以在String上使用chars()来获取Stream个字符,但是需要将int转换回char,因为chars()返回。
1
| "xyz". chars(). forEach(i -> System. out. print((char)i )); |
如果将Java 8与Eclipse集合一起使用,则可以使用带有lambda或方法引用的CharAdapter class forEach方法迭代String中的所有字符。
1
| CharAdapter. adapt("xyz"). forEach(c -> System. out. print(c )); |
此特定示例还可以使用方法引用。
1
| CharAdapter. adapt("xyz"). forEach(System. out::print ) |
注意:我是Eclipse Collections的提交者。
在这种情况下,您也可以使用lambda。
1 2 3 4
| String s ="xyz";
IntStream. range(0, s. length()). forEach(i -> {
char c = s. charAt(i );
}); |
对于Travers一个String,你也可以使用charAt()和字符串。
喜欢 :
1 2 3
| String str ="xyz"; // given String
char st = str. charAt(0); // for example we take 0 index element
System. out. println(st ); // print the char at 0 index |
charAt()是java中字符串处理的方法,它有助于遍历特定字符的字符串。
-
你知道for (char st:"xyz".toCharArray()) {}是什么吗?
-
这不会编译。
-
-1 off-topic(主题:for-each),并使用charAt而不是charAT