Python中文网

一个关于 编程问题的解答网站.

有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

避免Java中的重复字符串

我想问一个关于在Java中避免字符串重复的问题

上下文是一个带有如下标记和属性的XML:

<product id="PROD" name="My Product"...></product>

使用JibX,这种XML在如下类中进行编组/解编组:

public class Product{
private String id;
private String name;
// constructor, getters, setters, methods  and so on
}

该程序是一个长时间的批处理过程,因此需要创建、使用、复制产品对象等

嗯,问题是: 当我用Eclipse memory analyzer(MAT)这样的软件分析执行时,我发现了几个重复的字符串。例如,在id属性中,PROD值在2000个实例左右重复,以此类推

我怎样才能避免这种情况?Product类中的其他属性可能会在执行过程中更改其值,但属性如idname。。。不要经常改变

我读了一些关于字符串的东西。intern()方法,但我还没有使用,我不确定这是否是一个解决方案。我能在类中定义像静态final常量这样的属性中最常见的值吗

我希望我用正确的方式表达了我的问题。 非常感谢您的帮助或建议。提前谢谢


共 (3) 个答案

  1. # 1 楼答案

    众所周知,字符串对象可以通过两种方式创建,一种是使用文本,另一种是通过new运算符

    如果使用像String test = "Sample";这样的文本,那么它将被缓存在字符串对象池中。因此,这里不需要实习,因为默认情况下字符串对象将被缓存

    但是如果你创建一个字符串对象,比如string test=new string(“Sample”);那么这个字符串对象将不会被添加到字符串池中。因此,这里我们需要使用String test = new String("Sample").intern();将字符串对象强制推送到字符串缓存

    因此,建议使用字符串文字而不是新运算符

    所以在您的例子中,private static final String id=“PROD”;这是正确的解决方案

  2. # 2 楼答案

    虽然^{}可以通过将每个值减少到一个唯一的String实例来解决这个问题,但它会引入另一个问题:每个intern()-ed String都可以在JVM中存活很长时间。如果ID变化很大(即它们不是有限集合的一部分,但可以是任何值),那么从长远来看,这可能会产生巨大的负面影响

    Edit:我曾经声称intern()-ed字符串永远不能被GCed,但是@nanda证明了我对this JavaWorld article的错误。虽然这在一定程度上减少了intern()带来的问题,但它仍然没有完全移除:intern()提供的池无法控制,可能会在垃圾收集方面产生意外的结果)

    幸运的是Guava^{}接口和它的助手类^{}的形式提供了一个解决方案:使用^{}可以创建一个对象,它可以像String.intern()一样充当唯一String对象的“池”,除了池绑定到该实例,如果放弃该池,然后,内容也可以进行垃圾收集

  3. # 3 楼答案

    另一种解决方案:

    您可以尝试在@id属性上定义<xs:enumeration/>限制(如果您的域模型允许这样做的话)。如果JibX与JAXB或其他XML Java映射标准一样智能,那么可以将其映射为具有常量文本的Java enum,可以大量重用

    对于ID值,我会尝试这样做,因为它在我看来有点像一个枚举