我有两个文件正在读取,我在两个文件中都找到了一些行。我需要编写一个函数来检测两个文件中找到哪些行。现在我为此编写了代码,它将读取文件1的内容并将记录放入arraylist,然后读取文件2,对于file2中的每一行,我检查它是否在arraylist中找到,如果找到,我知道它是一个重复的行。现在我的问题是我在arraylist中保存完整的行,我想知道是否有可能将我读取的行转换为哈希码,然后我将这个哈希码保存到arraylist中,之后,我将比较这个哈希码到我从file2读取的行的哈希码,这是更好的节省内存的方法吗?
答案 0 :(得分:5)
如果两个哈希码不同,则行不同。如果两个哈希码相同,则这些行可能相同也可能不同。
如果您将文件存储在HashSet中,则查看行是否已存在是一种非常快速的操作。 HashSet在内部使用哈希码。
答案 1 :(得分:3)
这种方法可以节省内存,但不能保证匹配。哈希码的定义表明它们不是唯一的。如果要存储较小版本的字符串,则应存储字符串的摘要,如MD5。
以下是你如何获得摘要。
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
...
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] digestBytes = md.digest(string.getBytes());
MD5长度为16个字节,因此如果字符串长度超过8个字符(每个字符2个字节),这只会节省内存。
但除非你的文件非常大,否则你真的不需要担心内存,HashSet
答案会给你更好的结果。
修改强>
MD5确实会发生冲突,但不会在现实世界中发生冲突。它不应该用作加密哈希码,但在这种情况下可以正常工作。还有其他的摘要功能,如SHA256,它们碰撞的可能性较小,但它们的摘要大小较大。
答案 2 :(得分:2)
您正在寻找HashSet<String>
- 它将完全符合您的需求!
示例:
Set<String> file1 = ....// read line by line from file1
ArrayList<String> file2 = ... // - " - file2
for (String line : file1)
if (file2.contains(line))
duplicate found
答案 3 :(得分:0)
如果您真的担心记忆并愿意为了安全记忆而表现较差,您可以执行以下操作:
答案 4 :(得分:0)
你没有提到文件的大小限制,所以我假设它们可能足够大,无法将所有行存储在内存中。
所以,我建议采用以下方法:
连接两个文件以创建一个大文件。
使用“外部”排序算法,例如http://code.google.com/p/externalsortinginjava/对大文件进行排序。
读取已排序的文件,一次一行,并将每一行与之前的行进行比较(仅在内存中保留两行 - 当前行和上一行)。如果当前行和前一行相同,则该行将出现在两个原始文件中。
在计算的早期阶段经常需要“外部排序”,因为可用的内存要少得多。一种方法是/是Merge Sort,当与磁带一起使用时(记得磁带?),称为“磁带排序”。是的,我老了:-)
答案 5 :(得分:0)
如果您担心空间/内存问题,请将字符串转换为base36,然后再按照多人的建议将其存储在HashSet中。为了标准化,我建议从字符串中剥离所有空格和标点符号,并在创建base36等效项之前将其转换为小写。然后在HashSet
中,您最终得到HashSet<String>
,其中String包含字符串的base36编码而不是整个字符串。