将String.toCharArray()放入for循环

时间:2016-08-10 20:45:20

标签: java string char

我多次遇到如下代码:

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()只应在第一种情况下执行一次。

1 个答案:

答案 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++) {

这是字符串长度的线性。