Java 硬编码值与读取文件

Java 硬编码值与读取文件,java,data-structures,Java,Data Structures,这是一个关于硬编码数据效率的一般性问题——我正在用Java编写一个程序来进行一些化学分析,我需要使用不同元素的同位素丰度。我现在设置它的方式是,所有值(不需要修改)都存储为类中的最终字段,即 static final double C12Abundance = .989; static final double C12Mass = 12; 许多类似的程序将此类数据存储在XML文件中,然后从中读取值,如下所示: <compounds> <elements> <

这是一个关于硬编码数据效率的一般性问题——我正在用Java编写一个程序来进行一些化学分析,我需要使用不同元素的同位素丰度。我现在设置它的方式是,所有值(不需要修改)都存储为类中的最终字段,即

static final double C12Abundance = .989;
static final double C12Mass = 12;
许多类似的程序将此类数据存储在XML文件中,然后从中读取值,如下所示:

<compounds>
<elements>
    <element symbol='C' mono_isotopic_mass ='12.00000000000' abundance='.989'/>


是否有任何理由(性能、内存等)以这种方式读取?将其保留为字段似乎更容易。

配置文件包含属性,一般来说,这些属性会随着时间的推移而变化。我相信在你的情况下,这些都是固定不变的,从定义上讲永远不会改变。
出于这个原因,我会尽可能做更简单的事情,那就是把它们作为字段

这不是性能问题,只要性能不是问题,这只是代码库中更容易使用的问题


我建议您在类中将这些值提取为常量,这样您就可以始终导入它来访问这些值。

Java代码只能由Java编译器读取,而XML可以由任何合理的(表示支持XML的)语言读取。另外,如果你想增加一些价值,你不必重新编译所有东西。

就个人而言,如果价值永远不会改变,如果应用程序很小,我会选择硬编码。否则,我将选择conf数据的外部源


但每次人们告诉我价值观不会改变,这就意味着他们会改变,所以准备动态环境通常是一种方式。XML配置文件、数据库配置表等。

硬编码在性能和内存分配方面要快得多

从文件读取中获得的好处是代码的可重用性(使用不同的参数运行程序而无需重新编译)

请注意,从文件读取包含以下步骤:

  • 声明用于存储值的变量
  • 创建输入(流)对象
  • 用路径初始化它
  • 从FS打开文件
  • 找到要读取的正确行
  • 读取值
  • 将其存储在上面的变量中
  • 关闭输入(流)

  • 这是一个相当大的开销,而不是预先编译一个带有值的最终变量。如果你想硬编码这些值并想更改它们,你必须重新编译你的程序,这就是问题所在。从文件中读取数据有以下好处:

    • 您不必等待程序重新编译数据中的每个更改。对于一个相当大的程序,这可能需要时间
    • 您的用户甚至可以在不访问源的情况下更改数据
    • 您可以拥有不同的数据集,只需更改配置文件名即可在这些数据集之间进行切换
    也许这些对你来说都无关紧要;然后继续,把你的数据放到源代码中


    性能本身(如程序的性能)从来都不是问题,除非您的分析器这么说。但我不认为在启动时读取一小部分数据会是一个漫长的过程,所以我敢肯定你不会看到有什么不同。

    如果你用XML编写它们,你可以为不同的设备使用不同的值, e、 g假设您有一个名为
    item\u margin
    的维度,并且它需要根据设备的宽度而有所不同,因此在
    values/dimens.xml
    中,您有一个

    <dimen name="item_margin">0dp</dimen>
    
    <dimen name="item_margin">60dp</dimen>
    
    0dp
    
    在最小600dp宽度的设备中,您希望此余量60dp因此在 values-sw600dp/dimens.xml您有这个

    <dimen name="item_margin">0dp</dimen>
    
    <dimen name="item_margin">60dp</dimen>
    
    60dp
    

    通过这种方式,这些值会根据设备宽度自动选择,因此您不必检查设备宽度,也不必在Java代码中选择适当的值,如果您想模拟一个具有不同C12丰度的宇宙,则硬编码这些值意味着您必须重新编译程序


    可能还有其他原因:如果从外部文件读取值,则该文件用作文档,外部文件可能更容易检查错误,可能有工具生成该文件或将其用于运行程序以外的其他目的,…

    ,因为这些都是真正的通用常量,属性数量有限,您可以将它们放入代码中,但组织得很好

    public enum Element {
        //  Name Mass  Abund
        C12("C", 12.0, .989),
        He4(...),
        O32(...),
        ...;
    
        public final String name;
        public final double monoIsotopicMass;
        public final double abundancy;
    
        private Element(String name, double monoIsotopicMass, double abundancy) {
            this.name = name;
            this.monoIsotopicMass = monoIsotopicMass;
            this.abundancy = abundancy;
        }
    }
    
    for (Element elem : Element.values()) {
        if (elem.abundancy > 0.5) {
            ...
        }
    }
    

    如果在大型计算开始时只读取一次值,那么好处就不大了。感谢您的回复-我将保留硬编码的数据。在这种特殊情况下,我无法想象我必须更改这些值的场景(即使我这样做了,我也可以编辑源代码并重新编译),如果一项新的同行评审研究表明C12有点多(或少)呢?@Ingo大多数丰度都有很好的定义,如果它确实发生了变化,那么很可能是一个非常小的差异,并且是在一个特殊的环境中(即不是一般的大气条件)。另外,我只是硬编码了五个不同的元素,所以我可以随时返回并更新它。只是说,无意冒犯。将它们放在文件中的另一个很好的原因是,当您编写下一个程序时,需要更多的元素。还有下一个。等等在这种情况下,如果您有数据库和类在启动时读取它,您可以扩展它,而不会干扰旧程序或从中复制代码。没有冒犯,谢谢您的回复。这也是关于可重用性的一个好观点——如果我在另一个程序中使用这些值,我可能会在某个时候将其移动到一个外部文件中