【问题标题】:Alternative for String[]?替代字符串 []?
【发布时间】:2015-10-07 03:04:26
【问题描述】:

我有一个要求,我需要从文件中读取选项卡式分隔的数据并将其放入带有特定键的映射中。现在,我正在做什么来拆分数据,创建 String[] 并将其放入 hashmap 中。下面提供了有关我如何执行此操作的示例代码:

while ((line = bufferedReader.readLine()) != null) {
    String[] data = line.split("\t");
    myHashMap = new HashMap<String, String>();
    for (int i = 0; i < data.length; i++) {
           myHashMap.put("<key>"+i,data[i]);
    }
    <additional logic>
}

问题是我必须阅读近 2500 个文件,每个文件大约有 1000 行。这会导致高内存使用和性能问题。据我所知,字符串在内存方面总是更昂贵。所以我正在寻找更好的方法来解决这个要求。

感谢您的帮助。

【问题讨论】:

  • 使用int 代替"&lt;key&gt;"+int?
  • 如果您将输入视为文本字段的集合,那么您能做的最好的事情就是存储该文本。文本字段是否可以解释为具有含义并因此具有更紧凑的表示形式?它们中的任何一个是数字,还是从一小组值中得出的?
  • 为什么文件数量对内存使用很重要?无论如何,您正在一个一个地处理文件。
  • 查看 this 之前的 SO 帖子。它应该做你所追求的。
  • 您可以使用 8 位编码(Unicode 8 位、ASCII)对它们进行编码,但这样会失去 Java 中的功能。您可以使用其他类型的编码压缩每个字符串,并在您想使用它们时解压缩它们。但是你的“高内存使用和性能”和“总是更昂贵”的说法听起来很模糊,我猜你正在做所谓的“过早优化”;也就是说,您正在尝试解决一个定义不够明确甚至可能不存在的问题。

标签: java arrays string performance memory-management


【解决方案1】:

您真的需要将您的信息存储到地图中吗?

如果答案是否定的,您可以将其存储在一个列表中。

while ((line = bufferedReader.readLine()) != null) {
    String[] data = line.split("\t");
    myList = new ArrayList<String>(data.length);
    for (int i = 0; i < data.length; i++) {
           myList.add(data[i]);
    }
    // To get the elements, instead of using:
    myHashMap.get("<key>" + i);
    // use:
    myList.get(i);
    //<additional logic>
}

我正在考虑你关闭你的文件/缓冲区。

while ((line = bufferedReader.readLine()) != null) {
    List<String> myList = Arrays.asList(line.split("\t"));
    // To get the elements, instead of using:
    myHashMap.get("<key>" + i);
    // use:
    myList.get(i);
    //<additional logic>
}

除非您为哈希映射使用不同的键确实可以提高访问性能,否则您应该只使用数组的索引。

while ((line = bufferedReader.readLine()) != null) {
    String[] data = line.split("\t");
    // To get the elements, instead of using:
    myHashMap.get("<key>" + i);
    // use:
    data[i];
    //<additional logic>
}

【讨论】:

  • 这甚至不会编译,因为 ArrayList 没有两个类型参数。也和Arrays.asList一样,会更好。此外,在这种情况下,与 String[] 相比没有优势。
  • @JoeriHendrickx 我的错,我复制并粘贴了代码,错过了泛型中的 to 参数。
【解决方案2】:

如果您对大量字符串有疑问(根据您的估计,您将阅读大约 250 万条条目,所以您可能会),read up on String interning 并相应地设置 -XX:StringTableSize=N

我不明白您为什么要有效地将 HashMap 用作数组,但如果您真的想这样做,请确保使用大约正确的 initialCapacity and loadFactor 对其进行初始化。

【讨论】:

    猜你喜欢
    • 2012-07-29
    • 2013-02-21
    • 1970-01-01
    • 1970-01-01
    • 2015-09-22
    • 2017-06-01
    • 2015-10-06
    • 2017-10-09
    • 2019-07-15
    相关资源
    最近更新 更多