使用hashcode()和length()进行字符串比较

时间:2015-06-24 13:26:31

标签: java equality

在java(或使用相同哈希码函数的任何其他PL)中可以安全地说:

  

两个相等长度的字符串具有相同的哈希码,当且仅当它们是   等于

让我们假设哈希码函数将是

  

s [0] * 31 ^(n-1)+ s [1] * 31 ^(n-2)+ ... + s [n-1]

用例:

为了比较两个庞大的字符串集合,理论上使用option 1而不是option 2会更快,因为当String将缓存其值时,哈希码计算将完成一次:

选项1:

 for(String s1 : collection1){
   for(String s2 : collection2){
     if((s1.hashCode() == s2.hashCode()) && (s1.length()==s2.length()){
        System.out.println("matched");
     }
   }
 }

选项2

 for(String s1 : collection1){
   for(String s2 : collection2){
     if(s1.equals(s2)){
        System.out.println("matched");
     }
   }
 }

更新:

在@tobias_k评论之后,我意识到这个判断错了,所以我改变了问题。

  

对于任何两个相等的字符串,字符串的最大长度为M   当且仅当它们相等时,它们的哈希码才会相同

4 个答案:

答案 0 :(得分:4)

不,那是错的。

例如:

System.out.println ("ab " + "ab".hashCode());
System.out.println ("bC " + "bC".hashCode());

输出:

ab 3105
bC 3105

Equal hashCode并不代表相等的字符串,即使对于相同长度的字符串也是如此。

答案 1 :(得分:4)

  

当且仅当它们相等时,两个相等长度的字符串具有相同的哈希码

当然不是。获取长度为100的字符串。多个字符串的长度为100,而不是int个不同的字符串,因此必须有大量的冲突。

  

字符串的最大长度为M,对于任何两个相等长度的字符串,当且仅当它们相等时,它们的哈希码才相同

如果存在这样的长度M,则它最多为1(因此不是非常有用),如哈希码冲突的示例所示,即使对于Eren's中的长度为2的字符串和{{3答案。

为了使您的比较更快,您可以首先比较哈希码,然后仅在哈希码相同的情况下与equals进行比较。

for(String s1 : collection1){
    for(String s2 : collection2){
        if (s1.hashCode() == s2.hashCode() && s1.equals(s2)) {
            System.out.println("matched");
        }
    }
}

(注意:我没有说明这是否真的比首先使用equals更快。)

您还可以将collection1中的所有字符串放入Set,然后测试collection2中的字符串是否在该集合中。这基本上会做同样的事情:首先比较哈希码,如果找到具有相同哈希的条目,则使用equals

Set<String> setFromCollection1 = new HashSet<>(collection1);
for (String s : collection2) {
    if (setFromCollection1.contains(s)) {
        System.out.println("matched");
    }
}

答案 2 :(得分:1)

当且仅当它们相等时,两个相等长度的字符串具有相同的哈希码 - 不可能。

检查这个“FB”和“Ea”是否具有相同的长度并且具有相同的哈希码,但它们不相等。

    String s = new String("FB");
    String s1 = new String("Ea");
    System.out.println(s.hashCode()); //2236
    System.out.println(s1.hashCode()); //2236
    System.out.println(s.hashCode()==s1.hashCode()); //true
    System.out.println(s.equals(s1)); //false

答案 3 :(得分:1)

如果你正在寻找速度而你的匹配只会发生一次,那么下面的选项是最好的,它也被java中的地图实现使用

if (value1.hashCode() == value2.hashCode() && value1.equals(value2)) {
            System.out.println("matched!");
        }

但是如果你想多次匹配那么你应该寻找更好的算法来匹配,因为java实现是中等 http://www.javacodegeeks.com/2010/09/string-performance-exact-string.html帖子对字符串匹配算法性能有很好的总结。