假设我有一个非常长的字符串列表(40-1000个字符)。用户需要能够在列表中输入术语,列表将报告术语是否存在。
禁止存储,在长字符串旁边存储哈希是否更有效,然后当用户尝试查找时,它会哈希输入并将其与哈希列表进行比较?
There are similar answers here, but they aren't quite generalized enough.
答案 0 :(得分:3)
假设数据适合堆(即在内存中),最好的办法是使用Set(如果有与每个字符串相关的数据,则使用Map)。如果您确实需要List,则可以将存储从List更改为Set(使用HashSet)或维护单独的Set。
计算字符串hashcode()
的时间与字符串的长度成正比。假设正确实现的hashcode()
和适当大小的Set,查找字符串的时间相对于集合中的字符串数量(一旦计算出哈希码)是恒定的。
如果您在未排序的列表中使用equals()
,则查找时间可能与列表中的项目数成比例。如果您对列表进行排序,则可以使用比较次数进行二进制搜索,以查找与列表中项目数的对数成比例的一个字符串(并且每次比较都必须比较字符,直到找到差异为止)。 / p>
本质上,Set有点像保持字符串的哈希码一样方便,但它更进一步,并以这样的方式存储数据,以便快速直接跳转到集合的元素哈希码值。
请注意,只要找到差异,两个字符串的等于比较可以挽救,但可能必须比较两个字符串中的每个字符(当它们相等时)。如果您的字符串具有类似的长前缀,则会影响性能。有时,您可以从对数据类型内容的了解中获益(性能方面)。例如,如果所有字符串都以相同的1K前缀开头并且最后只有不同,那么您可以从覆盖equals()
实现以从结束到开始进行比较中受益,因此您可以更早地发现差异。
答案 1 :(得分:0)
你的问题不够具体。
首先,我假设你的意思是"我有 set 非常长的字符串",因为 list 是非常低效的状态查找结构
一些想法:
Arrays.equals
方法是内在的,但没有" raw" sun.misc.Unsafe
类中的内存比较方法。