我多次遇到如下代码:
for (char c : s.toCharArray()) {
....
}
我想知道s.toCharArray()
一次只能执行一次或是s.length
次?那下面的情况呢?
for (int i = 0; i < s.toCharArray().length; i++) {
....
}
受到评论的启发,做了一些测试:
案例1:执行时间:692.664
String s = "dfsdfjglsdlghsl";
for(int i = 0 ; i < 25; i++){
s += s;
}
long start_time = System.nanoTime();
for(char c : s.toCharArray()){
int i = 0;
}
long end_time = System.nanoTime();
double excution_time = (end_time - start_time)/1e6;
System.out.println(excution_time);
案例2:执行时间:688.217
String s = "dfsdfjglsdlghsl";
for(int i = 0 ; i < 25; i++){
s += s;
}
long start_time = System.nanoTime();
char[] carrays = s.toCharArray();
for(char c : carrays){
int i = 0;
}
long end_time = System.nanoTime();
double excution_time = (end_time - start_time)/1e6;
System.out.println(excution_time);
几乎一样。因此,s.toCharArray()
只应在第一种情况下执行一次。
答案 0 :(得分:2)
根据JLS Sec 14.14.2,对数组类型的增强for语句:
L1: L2: ... Lm:
for ({VariableModifier} TargetType Identifier : Expression) {
Statement
}
等同于以下基本声明:
T[] #a = Expression;
L1: L2: ... Lm:
for (int #i = 0; #i < #a.length; #i++) {
{VariableModifier} TargetType Identifier = #a[#i];
Statement
}
所以:
for (char c : s.toCharArray()) {
// ...
}
相当于:
T[] cs = s.toCharArray();
for (int i = 0; i < cs.length; i++) {
char c = cs[i];
// ...
}
所以s.toCharArray()
只执行一次。
然而,在
for (int i = 0; i < s.toCharArray().length; i++) {
在循环的每次迭代之前执行s.toCharArray()
。这是不可取的,因为它创建了一个长度为s.length()
的新数组,将字符复制到该数组中,然后获取数组的长度并丢弃数据。
由于循环执行s.length()
次,因此该循环至少是字符串长度的二次方。
使用它的计算成本更低:
for (int i = 0; i < s.length(); i++) {
这是字符串长度的线性。