为什么在Java7中,switch语句比if-else语句更快?

为什么在Java7中,switch语句比if-else语句更快?,java,if-statement,switch-statement,java-7,Java,If Statement,Switch Statement,Java 7,在Java7中,string对象可以是switch语句的表达式。有人能解释一下下面的陈述吗 Java编译器从使用字符串对象的switch语句生成的字节码通常比从链式if-then-else语句生成的字节码效率更高 它的效率更高,比如: switch(yourString) { case "text1": // your code break; case "text2": // etc. } 比记者: if (yourString.

Java7中,
string
对象可以是
switch
语句的表达式。有人能解释一下下面的陈述吗

Java编译器从使用字符串对象的switch语句生成的字节码通常比从链式if-then-else语句生成的字节码效率更高


它的效率更高,比如:

switch(yourString) {
    case "text1":
        // your code
        break;
    case "text2":
        // etc.
}
比记者:

if (yourString.equals("text1")) {
     // your code
} else if (yourString.equals("text2")) {
     // etc.
}

我猜这意味着什么,或者我理解的是,使用string从switch语句创建的字节码(编译java类时)比使用string从if-else语句创建的字节码更快、更高效。两者都可以做同样的工作,位切换显然更有效

switch (str) {
            case "A":  
                     // do something
                     break;
            case "B":
                     // do something
                     break;
            default: 
                     //do something
                     break;
}

if(str.equals("A")) {
//do something
} else if(str-equals("B")) {
//do something
} else {
//do something
}

字符串上的
开关
可以更快,原因与在字符串哈希集中查找可能比在字符串列表中查找快的原因相同:您可以在
O(1)
中进行查找,而不是在
O(N)
中进行查找,其中
N
是字符串数

回想一下,
switch
比一连串的
if-then-else
语句更有效,因为它是一个计算出的跳转:代码中的偏移量是基于该值计算的,然后执行到该偏移量的跳转。Java可以使用类似于散列映射和散列集的机制在字符串上使用类似的技巧。

Java代码 一个类有两个版本,例如

使用
if-then-else

public class IfThenElseClass {
    public static void main(String[] args) {
        String str = "C";
        if ("A".equals(str)) {

        } else if ("B".equals(str)) {

        } else if ("C".equals(str)) {

        }
    }
}
使用
开关

public class SwitchClass {
    public static void main(String[] args) {
        String str = "C";
        switch (str) {
            case "A":
                break;
            case "B":
                break;
            case "C":
                break;
        }
    }
}
字节码 让我们看看字节码。获取
if-then-else
版本的字节码:

Compiled from "CompileSwitch.java"
public class CompileSwitch {
  public CompileSwitch();
    Code:
       0: aload_0
       1: invokespecial #8  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: ldc           #16 // String C
       2: astore_1
       3: ldc           #18 // String A
       5: aload_1
       6: invokevirtual #20 // Method java/lang/String.equals:(Ljava/lang/Object;)Z
       9: ifne          28
      12: ldc           #26 // String B
      14: aload_1
      15: invokevirtual #20 // Method java/lang/String.equals:(Ljava/lang/Object;)Z
      18: ifne          28
      21: ldc           #16 // String C
      23: aload_1
      24: invokevirtual #20 // Method java/lang/String.equals:(Ljava/lang/Object;)Z
      27: pop
      28: return
}
Compiled from "CompileSwitch.java"
public class CompileSwitch {
  public CompileSwitch();
    Code:
       0: aload_0
       1: invokespecial #8 // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: ldc           #16 // String C
       2: astore_1
       3: aload_1
       4: dup
       5: astore_2
       6: invokevirtual #18 // Method java/lang/String.hashCode:()I
       9: lookupswitch  { // 3
                    65: 44
                    66: 56
                    67: 68
               default: 77
          }
      44: aload_2
      45: ldc           #24 // String A
      47: invokevirtual #26 // Method java/lang/String.equals:(Ljava/lang/Object;)Z
      50: ifne          77
      53: goto          77
      56: aload_2
      57: ldc           #30 // String B
      59: invokevirtual #26 // Method java/lang/String.equals:(Ljava/lang/Object;)Z
      62: ifne          77
      65: goto          77
      68: aload_2
      69: ldc           #16 // String C
      71: invokevirtual #26 // Method java/lang/String.equals:(Ljava/lang/Object;)Z
      74: ifne          77
      77: return
}
结论
  • 在第一个版本中,通过为每个条件调用
    equals
    方法来比较字符串,直到找到为止

  • 在第二个版本中,首先获得字符串的
    hashCode
    。然后将其与值进行比较​​<代码>哈希代码每个
    案例
    。请参阅
    查找开关
    。如果这些值中有任何一个​​仅在运行
    案例的代码时才会重复。否则,调用绑定案例的
    equals
    方法。这比只调用
    equals
    方法要快得多


当然可以。它的意思是:如果你在一大组If-than-else语句中比较字符串,你应该使用switch而不是switch,你不理解语句的哪一部分?非字符串特定版本:这就是我想要的答案。谢谢你,保罗