代码之家  ›  专栏  ›  技术社区  ›  Farhan stands with Palestine

Switch语句与Java中的Ifs

  •  0
  • Farhan stands with Palestine  · 技术社区  · 11 年前

    Herbert Schildt在“ 完整参考资料 “-第5章:

    switch语句通常比一组嵌套的if更有效。

    编译器编译switch语句时,会检查每个case常量,并创建一个“跳转表”,用于根据表达式的值选择执行路径。因此,如果需要在一大组值中进行选择,switch语句的运行速度将比使用if-else序列编码的等效逻辑快得多。编译器可以做到这一点,因为它知道case常量都是相同的类型,因此必须简单地与switch表达式进行比较,以确保相等。编译器对一长串if表达式一无所知。

    1. 他所说的“ 跳台 "?

    2. 开关不同于 if -声明中, switch 只能测试相等,而 如果 可以评估任何类型的 boolean 表示如果 switch(expression) 不匹配任何case常量,这意味着它位于 default 案例这不是不平等吗?这让我觉得 转换 如果 .

    3. 在同一本书的摘录中,他写道:

      if-then-else语句可以基于值或条件的范围测试表达式,而switch语句只能基于单个整数、枚举值或String对象测试表达式。

      这不意味着 如果 比…更强大 转换 ?

    4. 我曾在不同的Core Java项目中工作,但从未觉得有必要利用 转换 而且没有看到其他同事利用它。甚至一次都没有。为什么会有更强大的 转换 控制声明未能提前着陆 如果 在可用性方面?

    5 回复  |  直到 11 年前
        1
  •  5
  •   Simulant    11 年前

    1) 编译器为每个 case 语句,其中case条件是键,代码块是值。当 switch 语句在代码中执行时,case块的键可以直接访问case块。嵌套的位置 if 块,您需要检查并执行每个条件,然后才能找到输入条件代码块的正确块。

    把它想象成一个哈希表( 转换 案例 )与线性链接列表(用于嵌套 如果 语句),并比较查找特定值的时间。表的查找时间为 O(1) (只需在一次操作中获取)其中链接列表中的查找时间为 O(n) (看看每一项,直到你找到正确的)。

    3) 是的,一个 如果 语句可以更灵活地使用和表达,但在您希望 转换 不同值列表的不同代码块之间 转换 块的执行速度更快,可读性更强。

    4) 你从来没有 需要 使用 转换 因为嵌套 如果 s可以表达同样的意思,但在某些情况下它更优雅。但由于很少有好用的时间,程序员忘记了它,即使在更适合它的地方也不使用它。

    2) 从其他问题的答案中找出差异。

        2
  •  3
  •   brso05    9 年前

    我使用 switch 一直以来,如果你不使用它,你就错了Java。

    跳转表可以被认为是代码中的一个位置数组。例如,设想如下:

    case 0:
       // do stuff
       break;
    case 1:
       // do stuff 2
       break;
    case 3:
       // do stuff 3
       break;
    

    然后你有一个跳转表

    codeLocations[] = { do stuff, do stuff 2, do stuff 3 }.
    

    然后,要找到适用于情况1的正确代码位,Java只需转到 codeLocations[1] 。不需要实际的整数比较。

    显然,实际实现要比这复杂得多,因为它需要处理更多不同的情况,但它给出了想法。

    也不 if 也没有 转换 比其他人更强大。它们都是工具。你在问锤子是否比螺丝刀更有力。是的,锤子会把更多的东西敲入木头,但如果你使用螺丝刀,螺丝刀会做得更好:)

    要扩展“做java错误”这件事:

    Switch 是Java语言中的一个工具,添加它是有原因的。

    你可以用完全相同的问题 for 循环。您可以使用 对于 也可以使用 while 循环(尽管它可能需要编写更多的代码)。找个时间试试。

    这不意味着 虽然 “更强大”甚至“更有用” 对于 。它们是不同的工具,具有不同的优点和缺点。

    转换 如果 对于 虽然 。他们做类似的工作,在很多地方你都可以使用。然而,有一些明显的例子表明,一个优于另一个。

    如果您正在使用一种语言进行编程,而忽略了该语言工具包中的一个基本工具,那么您使用的语言是错误的。这并不是一个很难使用的晦涩特性,这是该语言中的主要流控制语句之一。

    如果木匠只使用锤子而不使用螺丝刀。。。他们做错了。同样,如果程序员从不使用重要的语言功能。。。他们做错了。

    这里有句谚语 “如果你唯一的工具是锤子,一切都像钉子” .

        3
  •  2
  •   phoog    11 年前

    1: 跳转表是跳转目标的表。跳转目标是代码中的一个地址,该地址对应于属于交换机中某个案例的代码。举个简单的例子,如果你的开关盒是0,1。。。N、 则N+1个目标将位于索引0、1。。。N。您只需计算打开的值,然后通过索引到表中来查找目标,而不是通过比较N+1次。这就是效率。

    2: default 这是一个不平等的例子,是的,但正如你所指出的,这是非常有限的。这是“不等于任何其他情况”的情况,但不能“小于给定值”或“大于…”

    3: 是的, if 更强大。然而 switch 有时效率更高。效率!=权力

    4: 功率!=效率但是,为了回答隐含的问题:更有效的switch语句没有被使用,因为你的同事没有使用它。你必须问他们为什么。也许是品味的问题,或者是对 转换 。switch语句的更高效率几乎总是不引人注意的,除非您处于对性能非常敏感的上下文中,所以人们通常对此一无所知。如果性能不是最重要的,那么可读性就是最重要的。在某些情况下,开发人员可能会考虑switch语句,并决定一系列If语句更容易阅读和理解。

        4
  •  2
  •   E_net4 Tunn    11 年前

    1) 在切换情况下,跳转表将代码段中的位置映射到特定情况。例如,考虑以下片段:

    int a;
    // a is manipulated here
    switch (a) {
        case 1: // address 0
            // ...
            break;
        case 2: // address 1
            // ...
            break;
        case 3: // address 2
            // ...
            break;
        default: // other cases
            // ...
            break;
    }
    

    将有一个跳转表将a=1映射到由 address 0 ,a=2至 address 1 等等。当观察生成的字节码时,这会变得更加明显。使用这种方法,字节码中的条件跳转数比if-else语句的情况小得多。

    2) 的确,if-else语句可以测试不相等性,但实现switch-case语句的相同行为需要链接if-elses语句。这是上述行为的等效版本。

    if (a==1) {
        // ...
    } else if (a==2) {
        // ...
    } else if (a==3) {
        // ...
    } else {
      // for any other cases
    }
    

    在某些时候,这可能是个人观点的问题,但在这种特定情况下,switch-case语句更具可读性。 但很自然,if else语句仍然是不可或缺的,你应该使用合适的工具来完成这项工作。 If-else switch-case ,但后者在某些地方可能会产生更好的代码。希望这能回答你问题的第三和第四部分。

        5
  •  0
  •   Margus    11 年前

    用外行的话来说,差异是微不足道的。

    二者都 有他们的 赞成的意见 欺骗 。在大多数情况下,你会 从不 使用 转换 -相反,您可以使用 散列表 带操作 或其他构造 那更好 可读性 .

    我建议你阅读高效Java或 https://code.google.com/p/guava-libraries/wiki/GuavaExplained

    在c#中,您可以这样写:

    class MyClass
    {
        static Dictionary<string, Func<MyClass, string, bool>> commands
            = new Dictionary<string, Func<MyClass, string, bool>>
        {
            { "Foo", (@this, x) => @this.Foo(x) },
            { "Bar", (@this, y) => @this.Bar(y) }
        };
    
        public bool Execute(string command, string value)
        {
            return commands[command](this, value);
        }
    
        public bool Foo(string x)
        {
            return x.Length > 3;
        }
    
        public bool Bar(string x)
        {
            return x == "";
        }
    }
    

    之后你可以

    var item = new MyClass();
    item.Execute("Foo","ooF");