【问题标题】:Difference in time complexity between storing data as a HashMap and record instance将数据存储为 HashMap 和记录实例之间的时间复杂度差异
【发布时间】:2022-01-26 00:49:54
【问题描述】:

对于我的一项学校作业,我必须使用 Java 解析 GenBank files。我必须存储和检索文件的内容以及提取的信息,以保持尽可能小的时间复杂度。使用 HashMaps 或将数据存储为记录之间有区别吗?我知道使用 HashMaps 会是 O(1),但是使用记录的可读性和不变性让我更喜欢使用它们。对象将存储在一个数组中。

这是我现在的方法

public static GenBankRecord parseGenBankFile(File gbFile) throws IOException {
    try (var fileReader = new FileReader(gbFile); var reader = new BufferedReader(fileReader)) {
        String organism = null;
        List<String> contentList = new ArrayList<>();

        while (true) {
            String line = reader.readLine();
            if (line == null) break; //Breaking out if file end has been reached

            contentList.add(line);
            
            if (line.startsWith("  ORGANISM  ")) {
                // Organism type found
                organism = line.substring(12);  // Selecting the correct part of the line
            }
        }
        // Loop ended
        var content = String.join("\n", contentList);
        return new GenBankRecord(gbFile.getName(),organism, content);
    }
}

GenBankRecord 如下:

record GenBankRecord(String fileName,String organism, String content) {
    @Override
    public String toString(){
        return organism;
    }
}

假设键值对与记录的字段相同,使用记录和HashMap有区别吗?

String current_organism = gbRecordInstance.organism();

String current_organism = gbHashMap.get("organism");

【问题讨论】:

  • “将数据存储为记录实例”是什么意思。 HashMap 是一种数据结构,“记录实例”可能意味着很多东西……它们不能直接比较。
  • “时间复杂度”是什么意思?你真的是这个意思,还是你指的是挂钟时间意义上的时间?我看到您的一个记录对象的名称中有“db”。你有记录的代码吗?您是在谈论哈希映射和文件访问之间的实际访问时间差吗?
  • Records 和HashMap 是苹果和橘子——比较它们没有任何意义。
  • 实际上,不,它没有澄清。严重地。首先以最自然的方式编写代码(您的 意见)。稍后考虑效率问题。你正在做的是过早的优化。这是个坏主意。 >您的
  • 旁注:您可以简单地使用try (var reader = Files.newBufferedReader(gbFile.toPath())) { 而不是try (var fileReader = new FileReader(gbFile); var reader = new BufferedReader(fileReader)) { 但是由于您将所有行都读入列表中,因此您可以只使用List&lt;String&gt; contentList = Files.readAllLines(gbFile.toPath());。然后,您必须在该列表中搜索 " ORGANISM " 行,但其他所有内容都已过时。

标签: java hashmap time-complexity record


【解决方案1】:

我必须存储和检索文件的内容以及提取的信息,以保持尽可能小的时间复杂度。

首先,我有点怀疑你们的老师是否真的这么说要求。仅针对时间复杂性进行优化没有多大意义。

复杂性不是效率。

大 O 复杂度与度量值(例如所用时间)本身无关。它实际上是关于随着某些变量变得非常大而度量(例如所用时间)变化的方式。

例如,HashMap.get(nameStr)someRecord.name 都是 O(1) 复杂度。

但它们在效率方面并不相同。使用 Java 17 record 类型或具有命名字段的常规 Java 类将比使用 HashMap 快几个数量级。 (而且它将使用更少数量级的内存。)

假设您的对象具有固定数量的命名字段,那么复杂性(即性能如何随着字段数量的不断增加而变化)甚至都无关紧要。

性能不是一切。

HashMaprecord 类之间的最大区别实际上在于它们提供的功能:

  • Map&lt;String, SomeType&gt; 提供一组名称/值对,其中:

    • 集合中的对数不固定
    • 名称不固定
    • 值的类型都是SomeType或子类型的实例。
  • record(或经典的class)可以被视为一组字段名/值对,其中:

    • 对的数量在编译时是固定的
    • 字段名称在编译时是固定的
    • 字段类型不必是任何单一给定类型的子类型。

正如@Louis Wasserman 评论的那样:

Records 和 HashMap 是苹果和橘子——比较它们没有任何意义。

实际上,您应该通过比较它们提供的功能/约束与您的应用程序实际需要的功能/约束来在记录和哈希图之间进行选择。

(您问题中的问题描述不够清楚,我们无法做出判断。)

效率问题可能是相关的,但它是次要问题。 (如果代码不满足功能需求,效率就无从谈起。)

复杂性与您的任务相关吗?

嗯……也许是的。但不在您正在查看的区域。

我对要求的解读是,其中之一是您能够有效地从内存数据结构中检索信息。

但到目前为止,您一直在考虑存储单个记录。检索意味着您有一组记录,并且您必须(有效地)检索特定记录,或者可能是一组符合某些条件的记录。这意味着您需要考虑表示集合的数据结构。

假设您有一组 N 记录(或其他)代表(例如)N 生物体:

  • 如果集合是List&lt;SomeRecord&gt;,则需要迭代列表以找到(例如)"cat" 的记录。那是O(N)

  • 如果集合是由生物体名称键入的HashMap&lt;String, SomeRecord&gt;,则可以在O(1) 中找到"cat" 记录。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-17
    • 2016-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多