gpt4 book ai didi

java - 在Java中存储和比较大量字符串

转载 作者:行者123 更新时间:2023-12-01 07:54:34 25 4
gpt4 key购买 nike

我的应用程序在 ArrayList 中存储大量(大约 700,000)字符串。字符串是从文本文件加载的,如下所示:

        List<String> stringList = new ArrayList<String>(750_000);

//there's a try catch here but I omitted it for this example
Scanner fileIn = new Scanner(new FileInputStream(listPath), "UTF-8");
while (fileIn.hasNext()) {
String s = fileIn.nextLine().trim();

if (s.isEmpty()) continue;
if (s.startsWith("#")) continue; //ignore comments

stringList.add(s);
}
fileIn.close();

稍后,使用以下代码将其他字符串与此列表进行比较:

    String example = "Something";
if (stringList.contains(example))
doSomething();

这种比较会发生数百(数千?)次。

<小时/>

这一切都有效,但我想知道是否可以做些什么来让它变得更好。我注意到,当加载 700K 字符串时,JVM 的大小从大约 100MB 增加到 600MB。字符串主要是这样的大小:

Blackened Recordings 
Divergent Series: Insurgent
Google
Pixels Movie Money
X Ambassadors
Power Path Pro Advanced
CYRFZQ

我可以做些什么来减少内存,或者这是可以预料的吗?总体来说有什么建议吗?

最佳答案

ArrayList是一个内存有效的。您的问题可能是由 java.util.Scanner 引起的。扫描仪在解析过程中创建大量临时对象(模式、匹配器等),不适合大文件。

尝试将其替换为java.io.BufferedReader:

List<String> stringList = new ArrayList<String>();
BufferedReader fileIn = new BufferedReader(new FileReader("UTF-8"));
String line = null;
while ((line = fileIn.readLine()) != null) {
line = line.trim();

if (line.isEmpty()) continue;
if (line.startsWith("#")) continue; //ignore comments

stringList.add(line);
}
fileIn.close();

参见 java.util.Scanner source code

要查明内存问题,请将任何内存分析器附加到您的 JVM,例如 VisualVM from JDK tools

已添加:

让我们做一些假设:

  1. 您有 700000 个字符串,每个字符串包含 20 个字符。
  2. 对象引用大小为 32 位,对象头 - 24,数组头 - 16,字符 - 16,int 32。

那么每个字符串将消耗 24+32*2+32+(16+20*16) = 456 位。

带有字符串对象的整个 ArrayList 将消耗大约 700000*(32*2+456) = 364000000 位 = 43.4 MB(非常粗略)。

关于java - 在Java中存储和比较大量字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31833901/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com