有大量长字符串需要比较,JDK提供的equals()方法实在太慢
想利用 String类的 hashCode() 方法相等来比较,但对于不同的长字符串来说 hashCode()重复的几率挺高
于是有个想法:
如果两个String 的 length()和hashCode()都相等,是否一定 equals()成立呢?(没有反向推的要求)
这个设想还未得到理论证明,请大家给点意见,谢谢!

解决方案 »

  1.   

    先不说成不成立,就hashCode()的速度比一定比equals()快,看看源代码就知道了:
    -------------------------------------
    public int hashCode() {
    int h = hash;
    if (h == 0) {
        int off = offset;
        char val[] = value;
        int len = count;            for (int i = 0; i < len; i++) {
                    h = 31*h + val[off++];
                }
                hash = h;
            }
            return h;
        }
    -----------------------------------------
    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;
        }
    最好还是自己写个算法。
      

  2.   


    >>如果两个String   的   length()和hashCode()都相等,是否一定   equals()成立呢?(没有反向推的要求)不一定.    但是这个概率应该比较低.  看看你的业务能否允许这个概率了.另外,求hashCode() 的jdk 代码:
    public int hashCode() {
    int h = hash;
    if (h == 0) {
        int off = offset;
        char val[] = value;
        int len = count;            for (int i = 0; i < len; i++) {
                    h = 31*h + val[off++];
                }
                hash = h;
            }
            return h;
        }如果你每个字符串只比较一次的话,那么hashCode() 不会比equals 快的.
      

  3.   

    JDK的equals已经是最快的算法了!OVER,谁让你的字符串太长了呢!
      

  4.   

    我是楼主,直接比较String 的 hashCode() 比 equals() 快很多,但由于 hashCode()返回的是 int,而在实际应用中字符串的数量肯定多于 int 的最大值
    所以 hashCode 是肯定有重复的,这点已经得到了证明,所以才想办法退而求其次PS:比较引用……肯定不成的哦。
      

  5.   

    我是楼主,不是字符串场,字符串的length()也就在100左右,但我有十几万、几十万字符串要比较。
      

  6.   

    如果 hashCode() 真的比 equals() 快,那楼主不妨把两种比较方式结合一下:先看 hashCode() 的比较结果,如果不相同就 OK 了,如果相同,再用 equals() 做比较。
      

  7.   

    回过头来再说 hashCode() 是不是真的比 equals() 快。从 1 楼给出的源代码看,如果一个字符串只是一次性地参与比较,确实计算 hashCode 的开销恐怕比直接使用 equals() 还要大。但如果是大量重复地参与比较,则 hashCode 只计算一次,还是能节省一些计算时间的。况且,实际上 hashCode 很可能在你试图进行比较之前就早已经计算好了,因为很多操作都会引发对 hashCode 的计算。
      

  8.   

    有很多“个”东西要比较
    就用多线程搞就得了贝
    用的着那么抠,都抠到hashCode()   是不是真的比   equals()   快吗?十几万次,几十万次,
    仅仅是因这两个方法产生的时间差距可以忽略不计了
    不如把时间和精力花在优化其他方面上
    另外,是不是快,我想,看源代码的长度是没用的
      

  9.   

    跟 12 楼的兄弟探讨一下。首先,多线程不是干这个用的。多线程解决的是,在不得不等待 IO 的时间里,怎么最大程度发挥 CPU 的作用(让 CPU 忙起来)。在本贴的这个问题里,要点不在于如何获取这几十万个字符串(如果真要从硬盘文件里取,可以考虑多线程),而在于如何让 CPU 用最小的代价把“比较”计算做完。即使用单线程,也可以让 CPU 跑成 100% 了,没必要搞什么多线程。你说的“不如把时间和精力花在优化其他方面上”,同意。其实,不知道楼主在其它方面是否已经优化得足够了,单就字符串比较而言,跟一次比较相关的程序一定也有不少,如果比较工作量相对可以忽略的话,当然也就不用想怎么优化了。第三,上面说的两种算法哪个快一些,显然不是根据源代码的长度,而是根据程序逻辑的  :)
      

  10.   

    9楼的方法不错。
    受其启发,不知是否可以先比较字符串的长度,不同再继续比较第一个字母,不同再继续下去,hashCode(),equals()。
      

  11.   

    晕死,字符串的比较当然先比较长度了,长度不一致,内容就不能是相等的,然后再用compareTo比较。字符串长度虽然长,如果不多的话,你可以为每一个字符串建立一个MD5值,不过这个和hashCode一个道理的。
      

  12.   

    StringUtils.isEmpty(StringUtils.difference(str1, str2))