Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么第二个代码比第一个更有效?_Java_Algorithm_Time Complexity - Fatal编程技术网

Java 为什么第二个代码比第一个更有效?

Java 为什么第二个代码比第一个更有效?,java,algorithm,time-complexity,Java,Algorithm,Time Complexity,我对两个代码感到困惑,为什么我在这里给出的第二个代码比第一个代码更有效 这两种代码都只是反转一个字符串,但第一种代码比另一种代码慢,我不明白为什么 第一个代码是: String reverse1(String s) { String answer = ""; for(int j = s.length() - 1; j >= 0; j--) { answer += s.charAt(j); } return answer; } 第二个代码是

我对两个代码感到困惑,为什么我在这里给出的第二个代码比第一个代码更有效

这两种代码都只是反转一个字符串,但第一种代码比另一种代码慢,我不明白为什么

第一个代码是:

String reverse1(String s) {
    String answer = "";
    for(int j = s.length() - 1; j >= 0; j--) {
        answer += s.charAt(j); 
    }
    return answer;
}
第二个代码是:

String reverse2(String s) {
    char answer[] = new char[s.length()]; 
    for(int j = s.length() - 1; j >= 0; j--) {
        answer[s.length() - j - 1] = s.charAt(j);
    }
    return new String(answer);
}

我无法理解第二段代码如何比第一段代码更有效,我希望您能对此有所了解。

字符串是不可变的。每当你做
answer+=s.charAt(j)它创建一个新对象。尝试使用
-XX:+PrintGCDetails
打印GC日志,并查看延迟是否由次要GC引起。

字符串是不可变的。每当你做
answer+=s.charAt(j)它创建一个新对象。尝试使用
-XX:+PrintGCDetails
打印GC日志,并查看延迟是否由次要GC引起。

第一个代码声明

String answer;
char answer[];
字符串是不可变的。因此,每个追加操作都会重新分配整个字符串,复制它,然后复制新字符

第二个代码声明

String answer;
char answer[];

数组是可变的,因此每次迭代只复制一个字符。最后一个字符串创建一次,而不是循环的每次迭代都创建一次。

第一个代码声明

String answer;
char answer[];
字符串是不可变的。因此,每个追加操作都会重新分配整个字符串,复制它,然后复制新字符

第二个代码声明

String answer;
char answer[];

数组是可变的,因此每次迭代只复制一个字符。最后的字符串只创建一次,而不是循环的每次迭代都创建一次。

您的问题可能很难准确回答,部分原因是答案取决于第一个版本的实际实现。这又取决于您使用的Java版本以及编译器决定执行的操作

假设编译器在编写第一个版本时保持原样,那么是的,第一个版本可能效率更低,因为它需要为反转过程中的每个步骤分配一个新字符串。相反,第二个版本只维护一个字符数组

但是,如果编译器足够聪明,可以使用
StringBuilder
,那么答案就会改变。考虑下面的第一个版本:

String reverse1(String s) {
    StringBuilder answer = new StringBuilder();
    for (int j = s.length() - 1; j >= 0; j--) 
        answer.append(s.charAt(j));

    return answer;
}
在引擎盖下,
StringBuilder
使用字符数组实现。因此,调用
StringBuilder#append
与第二个版本有些相似,即它只是在缓冲区的末尾添加新字符


这样,如果你的第一个版本使用文字>代码>字符串,那么它比第二个版本更低效,但是使用<代码> StringBuilder < /代码>它可能与第二个版本一致。

< P>你的问题可能很难确切地回答,部分原因在于答案将取决于第一个版本的实际实现。这又取决于您使用的Java版本以及编译器决定执行的操作

假设编译器在编写第一个版本时保持原样,那么是的,第一个版本可能效率更低,因为它需要为反转过程中的每个步骤分配一个新字符串。相反,第二个版本只维护一个字符数组

但是,如果编译器足够聪明,可以使用
StringBuilder
,那么答案就会改变。考虑下面的第一个版本:

String reverse1(String s) {
    StringBuilder answer = new StringBuilder();
    for (int j = s.length() - 1; j >= 0; j--) 
        answer.append(s.charAt(j));

    return answer;
}
在引擎盖下,
StringBuilder
使用字符数组实现。因此,调用
StringBuilder#append
与第二个版本有些相似,即它只是在缓冲区的末尾添加新字符


>如果你的第一个版本使用文字>代码> String ,那么它比第二个版本更低效,但是使用<代码> StringBuilder < /代码>它可能与第二个版本相符合。

<代码> String 对象是不可变的,每次添加操作时,都会创建另一个对象,分配空间等等,因此,当需要连接多个字符串时,效率非常低


你的字符数组方法很适合你的特定需求,但是如果你需要更多的通用字符串连接支持,你可以考虑<代码> StringBuilder < /C> > /P> < P> <代码> String < /Cord>对象是不可变的,每次添加操作时,都会创建另一个对象,分配空间等等,因此,当需要连接多个字符串时,效率非常低


您的字符数组方法很适合您的特定需求,但是如果您需要更多的泛型字符串连接支持,可以考虑<代码> StringBuilder < /Cult>

< p>在这个代码中,在每个循环迭代中创建一个新的字符串对象,因为字符串是不可变的类

String reverse1(String s) {
    String answer = "";
    for (int j = s.length() - 1; j >= 0; j--)
        answer += s.charAt(j);
    return answer;
}
在这段代码中,您已经为char数组分配了内存,您的代码将在最后一行只创建一个字符串,所以它更高效

String reverse2(String s) {
    char answer[] = new char[s.length()];
    for (int j = s.length() - 1; j >= 0; j--)
        answer[s.length() - j - 1] = s.charAt(j);
    return new String(answer);
}

在这段代码中,您将在每个循环迭代中创建一个新的String对象,因为String是不可变的类

String reverse1(String s) {
    String answer = "";
    for (int j = s.length() - 1; j >= 0; j--)
        answer += s.charAt(j);
    return answer;
}
在这段代码中,您已经为char数组分配了内存,您的代码将在最后一行只创建一个字符串,所以它更高效

String reverse2(String s) {
    char answer[] = new char[s.length()];
    for (int j = s.length() - 1; j >= 0; j--)
        answer[s.length() - j - 1] = s.charAt(j);
    return new String(answer);
}
为什么第二个代码比第一个更有效


字符串是不可变的,通过
answer+=s.charAt(j)在每个循环中创建一个新的字符串实例,这会降低代码的速度


建议您在单线程上下文中使用
StringBuilder
,而不是字符串,以提高性能和可读性(可能比固定大小的字符数组稍慢,但可读性更好):

为什么第二个代码比第一个更有效


字符串是不可变的,通过
answer+=s.charAt(j)在每个循环中创建一个新的字符串实例,这会降低代码的速度


建议您在单线程上下文中使用
StringBuilder
,而不是字符串,用于