the following classes, is the time complexity of method1 and method2 the same? why.
public class Test { public static final int MB = 1024 * 1024; public static final long TIMES = 500000000L; public static void main(String[] args) throws InterruptedException { method1(); method2(); } //From the bytecode point of view, method1 repeats new StringBuilder Then append, obviously not efficient. JIT optimization is excluded here. public static void method1() { String s = ""; for (int i = 0; i < 100; i++) { s += "a"; } System.out.println(s); } public static void method2() { // //b StringBuilder sb = new StringBuilder(); for (int i = 0; i < 100; i++) { sb.append("a"); } System.out.println(sb.toString()); } }
My answer at the time was that it should be the same, because I really couldn't find a way to say they were different. But there must be a reason for the interviewer to ask this question. I only analyze it from the aspect of efficiency. For example, method1 will be done through StringBuilder, which is not as good as the latter method2. Later, the interviewer corrected the question and said that it was considered from the time complexity. I told him directly, all I could see was the same, maybe method2 would be better. The interviewer didn't seem very satisfied.
When I came back, I started to look at the source code, and it felt unreliable. Later, I saw that someone analyzed it with bytecode. You can see how the compiler translates. It has been confirmed that it is the same as what I think. The bytecode is as follows:
Compiled from "Test.java" public class Test extends java.lang.Object{ public static final int MB; public static final long TIMES; public Test(); Code: 0: aload_0 1: invokespecial #16; //Method java/lang/Object."<init>":()V 4: return public static void main(java.lang.String[]) throws java.lang.InterruptedException; Code: 0: invokestatic #27; //Method method1:()V 3: invokestatic #30; //Method method2:()V 6: return public static void method1(); Code: 0: ldc #35; //String 2: astore_0 3: iconst_0 4: istore_1 5: goto 31 8: new #37; //class java/lang/StringBuilder 11: dup 12: aload_0 13: invokestatic #39; //Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String; 16: invokespecial #45; //Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V 19: ldc #48; //String a 21: invokevirtual #50; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 24: invokevirtual #54; //Method java/lang/StringBuilder.toString:()Ljava/lang/String; 27: astore_0 28: here 1, 1 31: iload_1 32: bipush 100 34: if_icmplt 8 37: getstatic #58; //Field java/lang/System.out:Ljava/io/PrintStream; 40: aload_0 41: invokevirtual #64; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 44: return public static void method2(); Code: 0: new #37; //class java/lang/StringBuilder 3: dup 4: invokespecial #73; //Method java/lang/StringBuilder."<init>":()V 7: astore_0 8: iconst_0 9: istore_1 10: goto 23 13: aload_0 14: ldc #48; //String a 16: invokevirtual #50; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 19: pop 20: here 1, 1 23: iload_1 24: bipush 100 26: if_icmplt 13 29: getstatic #58; //Field java/lang/System.out:Ljava/io/PrintStream; 32: aload_0 33: invokevirtual #54; //Method java/lang/StringBuilder.toString:()Ljava/lang/String; 36: invokevirtual #64; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 39: return }