java中如何快速比较两个 String

tyxsoft 2008-02-18 03:29:26
有大量长字符串需要比较,JDK提供的equals()方法实在太慢
想利用 String类的 hashCode() 方法相等来比较,但对于不同的长字符串来说 hashCode()重复的几率挺高
于是有个想法:
如果两个String 的 length()和hashCode()都相等,是否一定 equals()成立呢?(没有反向推的要求)
这个设想还未得到理论证明,请大家给点意见,谢谢!
...全文
974 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
tyxsoft 2008-02-21
  • 打赏
  • 举报
回复
谢谢大家,结贴~!
hanfengthinker 2008-02-20
  • 打赏
  • 举报
回复
十三楼不错,学习
liang8305 2008-02-19
  • 打赏
  • 举报
回复
有很多“个”东西要比较
就用多线程搞就得了贝
用的着那么抠,都抠到hashCode() 是不是真的比 equals() 快吗?

十几万次,几十万次,
仅仅是因这两个方法产生的时间差距可以忽略不计了
不如把时间和精力花在优化其他方面上


另外,是不是快,我想,看源代码的长度是没用的
  • 打赏
  • 举报
回复
楼主的意思是否比较两个文件中的不同呢?
Ryo_Hazuki 2008-02-19
  • 打赏
  • 举报
回复
StringUtils.isEmpty(StringUtils.difference(str1, str2))
nwsl 2008-02-19
  • 打赏
  • 举报
回复
9楼的方法不错。^^,学到很多。
healer_kx 2008-02-19
  • 打赏
  • 举报
回复
晕死,字符串的比较当然先比较长度了,长度不一致,内容就不能是相等的,然后再用compareTo比较。

字符串长度虽然长,如果不多的话,你可以为每一个字符串建立一个MD5值,不过这个和hashCode一个道理的。

zhawk008 2008-02-19
  • 打赏
  • 举报
回复
9楼的方法不错。
受其启发,不知是否可以先比较字符串的长度,不同再继续比较第一个字母,不同再继续下去,hashCode(),equals()。。。。
maquan 2008-02-19
  • 打赏
  • 举报
回复
跟 12 楼的兄弟探讨一下。

首先,多线程不是干这个用的。多线程解决的是,在不得不等待 IO 的时间里,怎么最大程度发挥 CPU 的作用(让 CPU 忙起来)。在本贴的这个问题里,要点不在于如何获取这几十万个字符串(如果真要从硬盘文件里取,可以考虑多线程),而在于如何让 CPU 用最小的代价把“比较”计算做完。即使用单线程,也可以让 CPU 跑成 100% 了,没必要搞什么多线程。

你说的“不如把时间和精力花在优化其他方面上”,同意。其实,不知道楼主在其它方面是否已经优化得足够了,单就字符串比较而言,跟一次比较相关的程序一定也有不少,如果比较工作量相对可以忽略的话,当然也就不用想怎么优化了。

第三,上面说的两种算法哪个快一些,显然不是根据源代码的长度,而是根据程序逻辑的 :)
Icicly_qcmos 2008-02-18
  • 打赏
  • 举报
回复
9楼方法不错
maquan 2008-02-18
  • 打赏
  • 举报
回复
回过头来再说 hashCode() 是不是真的比 equals() 快。

从 1 楼给出的源代码看,如果一个字符串只是一次性地参与比较,确实计算 hashCode 的开销恐怕比直接使用 equals() 还要大。但如果是大量重复地参与比较,则 hashCode 只计算一次,还是能节省一些计算时间的。

况且,实际上 hashCode 很可能在你试图进行比较之前就早已经计算好了,因为很多操作都会引发对 hashCode 的计算。
maquan 2008-02-18
  • 打赏
  • 举报
回复
如果 hashCode() 真的比 equals() 快,那楼主不妨把两种比较方式结合一下:

先看 hashCode() 的比较结果,如果不相同就 OK 了,如果相同,再用 equals() 做比较。
老紫竹 2008-02-18
  • 打赏
  • 举报
回复
如果有那没多,我建议你在数据库层面优化一下。
给每个字符串做一个MD5的编码,前面附加字符串的长度,这样,在生成字符串的时候,就已经做了,可以加快比较速度。

tyxsoft 2008-02-18
  • 打赏
  • 举报
回复
我是楼主,不是字符串场,字符串的length()也就在100左右,但我有十几万、几十万字符串要比较。
tyxsoft 2008-02-18
  • 打赏
  • 举报
回复
我是楼主,直接比较String 的 hashCode() 比 equals() 快很多,但由于 hashCode()返回的是 int,而在实际应用中字符串的数量肯定多于 int 的最大值
所以 hashCode 是肯定有重复的,这点已经得到了证明,所以才想办法退而求其次

PS:比较引用……肯定不成的哦。
老紫竹 2008-02-18
  • 打赏
  • 举报
回复
JDK的equals已经是最快的算法了!

OVER,谁让你的字符串太长了呢!
zhaining522 2008-02-18
  • 打赏
  • 举报
回复
有创意 但是俺也不知道

但是要是由于字符串比较长 那么能不能就去比较引用呢

这样的一个思路你看怎么样 呵呵
枫叶rain 2008-02-18
  • 打赏
  • 举报
回复
应该是对的
我测试了一下感觉是对的
不知道有没有特殊的情况
hcmsxy 2008-02-18
  • 打赏
  • 举报
回复

>>如果两个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 快的.
91大白兔奶糖 2008-02-18
  • 打赏
  • 举报
回复
先不说成不成立,就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;
}


最好还是自己写个算法。

62,623

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧