【发布时间】:2011-01-27 22:37:03
【问题描述】:
所以我想对字符串中的每个字符进行迭代。
所以我想:
for (char c : "xyz")
但我得到一个编译器错误:
MyClass.java:20: foreach not applicable to expression type
我该怎么做?
【问题讨论】:
标签: java string loops foreach char
所以我想对字符串中的每个字符进行迭代。
所以我想:
for (char c : "xyz")
但我得到一个编译器错误:
MyClass.java:20: foreach not applicable to expression type
我该怎么做?
【问题讨论】:
标签: java string loops foreach char
如果您使用 Java 8,则可以在 String 上使用 chars() 来获得 Stream 的字符,但您需要将 int 转换回 char,因为 chars() 返回一个IntStream。
"xyz".chars().forEach(i -> System.out.print((char)i));
如果您将 Java 8 与 Eclipse Collections 一起使用,则可以使用带有 lambda 或方法引用的 CharAdapter 类 forEach 方法来迭代 String 中的所有字符。
Strings.asChars("xyz").forEach(c -> System.out.print(c));
这个特定的例子也可以使用方法引用。
Strings.asChars("xyz").forEach(System.out::print)
注意:我是 Eclipse Collections 的提交者。
【讨论】:
不幸的是,Java 没有使 String 实现 Iterable<Character>。这很容易做到。有StringCharacterIterator,但它甚至没有实现Iterator...所以自己做吧:
public class CharSequenceCharacterIterable implements Iterable<Character> {
private CharSequence cs;
public CharSequenceCharacterIterable(CharSequence cs) {
this.cs = cs;
}
@Override
public Iterator<Character> iterator() {
return new Iterator<Character>() {
private int index = 0;
@Override
public boolean hasNext() {
return index < cs.length();
}
@Override
public Character next() {
return cs.charAt(index++);
}
};
}
}
现在你可以(有点)轻松地运行for (char c : new CharSequenceCharacterIterable("xyz"))...
【讨论】:
在 Java 8 中我们可以这样解决:
String str = "xyz";
str.chars().forEachOrdered(i -> System.out.print((char)i));
chars() 方法返回IntStream,如doc 中所述:
返回一个 int 流,对 char 值进行零扩展 顺序。任何映射到代理代码点的字符都会被传递 通过未解释。如果在流发生时序列发生了突变 正在读取,结果未定义。
forEachOrdered 而不是forEach?forEach 的行为是明确的不确定性,因为forEachOrdered 对该流的每个元素执行操作,如果流具有定义的遇到顺序,则按照 流的遇到顺序 .所以forEach 不保证订单会被保留。另请查看question 了解更多信息。
我们也可以使用codePoints() 进行打印,请参阅此answer 了解更多详情。
【讨论】:
在这种情况下,您也可以使用 lambda。
String s = "xyz";
IntStream.range(0, s.length()).forEach(i -> {
char c = s.charAt(i);
});
【讨论】:
另一个有用的解决方案,您可以将此字符串用作字符串数组
for (String s : "xyz".split("")) {
System.out.println(s);
}
【讨论】:
split() 映射到多个 Java 字符(几乎所有表情符号都是这种情况),它就不起作用。例如,您的示例的这种变体将循环四次而不是三次:for (String s : "x?z".split("")) { System.out.println(s); }
对于 Travers 一个字符串,您还可以将 charAt() 与字符串一起使用。
喜欢:
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()) {}是什么吗?
String s = "xyz";
for(int i = 0; i < s.length(); i++)
{
char c = s.charAt(i);
}
【讨论】:
您需要使用 String 类的toCharArray() 方法将 String 对象转换为 char 数组:
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);
}
【讨论】:
在String 中对每个char 进行for-each 的最简单方法是使用toCharArray():
for (char ch: "xyz".toCharArray()) {
}
这为您提供了 for-each 构造的简洁性,但不幸的是,String(它是不可变的)必须执行防御性副本以生成 char[](它是可变的),因此会有一些成本损失。
[
toCharArray()返回]一个新分配的字符数组,它的长度就是这个字符串的长度,其内容被初始化为包含这个字符串所代表的字符序列。
迭代数组中的字符有更详细的方法(常规 for 循环、CharacterIterator 等),但如果您愿意支付费用,toCharArray() for-each 是最简洁的。
【讨论】:
toCharArray( ) 被调用了 3 次?
211900000,完成 for (char c : str.toCharArray()) { } 所需的时间约为 250 毫秒,而完成 for (char c : charArray) { } 所需的时间小于 10 毫秒。当然,这些时间值将取决于硬件,但要点是一种方法比另一种方法成本高得多。
toCharArray() 不在循环体内;它只被调用一次,然后循环遍历该结果数组。 (for-each 循环不同于一般的 for-loop,后者在每次迭代时评估停止条件。)