比较Java中字符串的最快方法是什么?

Med*_*tor 28 java string

在Java中比较两个字符串最快的是什么?

有比平等更快的东西吗?

编辑:我无法帮助澄清问题.

我有两个字符串,按字母顺序排序,完全相同的大小

示例:abbcee和abcdee

字符串最长可达30个字符

Bal*_*usC 32

我不认为Sun Oracle还没有将标准优化String#equals()到最大值.所以,我希望它已经是最快捷的方式了.如果你想了解它们是如何实现的,请在它的源代码中查看一下.这是一个摘录:

public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String anotherString = (String)anObject;
        int n = count;
        if (n == anotherString.count) {
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = offset;
            int j = anotherString.offset;
            while (n-- != 0) {
                if (v1[i++] != v2[j++])
                    return false;
            }
            return true;
        }
    }
    return false;
}
Run Code Online (Sandbox Code Playgroud)

  • @Stephan:那会更低效.`hashCode()`循环遍历字符串的所有字符以执行计算.如果`hashCode()`毕竟不一样,那么`equals()`基本上需要第二次遍历所有字符*. (9认同)
  • @BalusC这只是事实的一部分.一旦计算出来,`hashCode()`方法将哈希码存储到int中,因此下一次比较将非常快. (6认同)
  • 请注意 String::equals 和许多其他 String 方法是内在函数,由编译器替换为特定体系结构的预烘焙组装 blob。Java 代码仅在内部函数就位之前相关,因此几乎永远不会相关。 (2认同)

Ste*_*han 25

使用哈希码比较相同长度的字符串:

public static boolean equals(final String s1, final String s2) {
return s1 != null && s2 != null && s1.hashCode() == s2.hashCode()
    && s1.equals(s2);
}
Run Code Online (Sandbox Code Playgroud)

你可以测试它,我的结果是4000000比较操作,包括相同,相同和不同的字符串:

String.equals(String):  177081939
equals(String, String):  44153608
Run Code Online (Sandbox Code Playgroud)

注意:计算新字符串对象的hashCode需要一些计算时间,然后hashCode存储在对象中.因此,如果重用字符串对象,我建议的改进只会比默认比较快.在我的应用程序中,我使用String常量并在集合中存储字符串.使用我的方法对字符串进行多次比较对我来说实际上更快,但它可能不是一般的.

如果该方法始终与新字符串一起使用,compare("a", "b")则不会有任何改进.

因此,比较字符串的最快方法取决于:

  • 是否重用字符串对象(如从集合中重用)或始终是新的(如输入流)
  • 你的琴弦是否有不同的长度
  • 字符串的开头或结尾是否有不同的字符串
  • 您的编程风格,使用了多少常量
  • 你使用String.intern()

忽略这些事实,大多数程序都可以使用String.equals().

  • 我认为值得一提的是,可能存在一些哈希码冲突,因此比较哈希将返回误报的可能性非常小.这解释了你仍然必须使用equals的事实.出于这个原因,我认为如果大多数字符串相等,这将会更慢. (5认同)
  • 这怎么快?你仍然使用`s1.equals(s2)`. (2认同)

ung*_*rys 5

我尝试了不同的字符串比较组合(代码在这里):

1. s1.equals(s2)
2. s1.length() == s2.length() && s1.hashCode() == s2.hashCode() && s1.equals(s2)
3. s1.hashCode() == s2.hashCode() && s1.equals(s2);
4. s1.length() == s2.length() && s1.equals(s2);
Run Code Online (Sandbox Code Playgroud)

我使用了 40 个字符长度的字符串,在 10000000000L 次迭代中并且在任何迭代之前我重新初始化了字符串。

对于同样的刺痛,我得到了:

equal: 2873 milis ???
equal: 21386 milis
equal: 7181 milis
equal: 2710 milis ???
Run Code Online (Sandbox Code Playgroud)

对于相同大小的字符串,但最后一个字符不同,我得到了:

different: 3011 milis
different: 23415 milis
different: 6924 milis
different: 2791 milis
Run Code Online (Sandbox Code Playgroud)

对于不同的大小,几乎相同的字符串,但在 s2 的末尾添加了一个字符:

different size: 3167 milis
different size: 5188 milis
different size: 6902 milis
different size: 2951 milis
Run Code Online (Sandbox Code Playgroud)

在我看来,最好在 equals() 之前先使用 string.length() 比较。

但这几乎一点都不重要,因为在这种情况下,我有 10^10 个字符串与 40 个字符长度的比较,而对我来说奇怪的是,对于相等的字符串,当我首先比较字符串长度时,我有更好的速度.

  • 我认为你的数据有问题。当您比较相同长度的字符串时,算法 4(比较长度,然后使用 .equals())如何比算法 1(仅使用 .equals() 进行比较)更快。对于这些情况,算法 4 会进行不必要的字符串长度比较,该比较将始终返回 true。 (6认同)