我很好奇,想看看的Java和Scala如何實現對字符串開關:接通字符串
class Java
{
public static int java(String s)
{
switch (s)
{
case "foo": return 1;
case "bar": return 2;
case "baz": return 3;
default: return 42;
}
}
}
object Scala {
def scala(s: String): Int = {
s match {
case "foo" => 1
case "bar" => 2
case "baz" => 3
case _ => 42
}
}
}
看起來像Java接通的哈希碼,然後做一個字符串比較:
0: aload_0
1: dup
2: astore_1
3: invokevirtual #16 // Method java/lang/String.hashCode:()I
6: lookupswitch { // 3
97299: 40
97307: 52
101574: 64
default: 82
}
40: aload_1
41: ldc #22 // String bar
43: invokevirtual #24 // Method java/lang/String.equals:(Ljava/lang/Object;)Z
46: ifne 78
49: goto 82
52: aload_1
53: ldc #28 // String baz
55: invokevirtual #24 // Method java/lang/String.equals:(Ljava/lang/Object;)Z
58: ifne 80
61: goto 82
64: aload_1
65: ldc #30 // String foo
67: invokevirtual #24 // Method java/lang/String.equals:(Ljava/lang/Object;)Z
70: ifne 76
73: goto 82
76: iconst_1
77: ireturn
78: iconst_2
79: ireturn
80: iconst_3
81: ireturn
82: bipush 42
84: ireturn
相比之下,斯卡拉似乎可以與所有情況進行比較:
0: aload_1
1: astore_2
2: ldc #16 // String foo
4: aload_2
5: invokevirtual #20 // Method java/lang/Object.equals:(Ljava/lang/Object;)Z
8: ifeq 16
11: iconst_1
12: istore_3
13: goto 47
16: ldc #22 // String bar
18: aload_2
19: invokevirtual #20 // Method java/lang/Object.equals:(Ljava/lang/Object;)Z
22: ifeq 30
25: iconst_2
26: istore_3
27: goto 47
30: ldc #24 // String baz
32: aload_2
33: invokevirtual #20 // Method java/lang/Object.equals:(Ljava/lang/Object;)Z
36: ifeq 44
39: iconst_3
40: istore_3
41: goto 47
44: bipush 42
46: istore_3
47: iload_3
48: ireturn
是否可以說服Scala採用散列碼技巧?我寧願O(1)解決方案的O(n)解決方案。在我的真實代碼中,我需要比較33個可能的關鍵字。
我不認爲Java會一直這樣做,保證所有給出的字符串都有不同的哈希碼?這個檢查可能是在解釋器(JVM)中完成的,如果所有字符串都計算爲不同的散列值,則只選擇散列碼解決方案 – smac89 2015-03-30 20:12:19
@ Smac89散列衝突根本沒有問題。 Java將簡單地跳轉到相同的地方,然後做2個字符串比較而不是1.另外,編譯器知道所有的字符串以及它們的所有hashcode。 JVM不需要動態分析情況。 – fredoverflow 2015-03-30 20:14:17
我也很好奇......現在Java 8出來了,Scala仍然有用嗎? – 2015-03-30 20:21:09