我正在读取二进制文件,并希望将字节转换为US ASCII字符串。有没有办法在new
上调用String
来避免在字符串文字池中创建多个语义上相等的String
对象?我认为这可能是不可能的,因为这里不可能使用双引号引入String
个对象。这是对的吗?
private String nextString(DataInputStream dis, int size)
throws IOException
{
byte[] bytesHolder = new byte[size];
dis.read(bytesHolder);
return new String(bytesHolder, Charset.forName("US-ASCII")).trim();
答案 0 :(得分:2)
您可以在字符串上调用intern()方法,以确保整个JVM的方法。
String s = new String(bytes, "US-ASCII").intern();
您不会再避免再次创建初始字符串,但您将节省存储空间。
话虽如此,实习字符串的存储空间有限,因此请谨慎使用。一个更好的选择可能是使用字符串作为键和值来实现HashMap,并检查字符串是否已经存在并且如果它已经存在则获取它,如果不存在则插入它。这样你就不会有这样的内存限制。
答案 1 :(得分:2)
您必须将字节数组缓存映射到字符串,然后在创建新字符串之前在缓存中搜索任何相等的值。
你可以像Yishai发布的那样用intern()
实习现有的字符串 - 这不会阻止你从创建更多的字符串,但它会创造除第一个之外的所有字符串(对于任何字符)序列)非常短暂。另一方面,它会使所有不同的琴弦确实存在很长时间。
您可以使用Map<String, String>
:
String tmp = new String(bytesHolder, Charset.forName("US-ASCII")).trim();
String cached = cache.get(tmp);
if (cached == null)
{
cached = tmp;
cache.put(tmp, tmp);
}
return cached;
你甚至可以投入更多精力并最终使用LRU缓存,这样它就能保留N个最近获取的字符串,并在需要时丢弃其他字符串。
正如我所说,这些都没有减少首先创建的字符串数量 - 但这可能是你情况下的一个问题吗? GC已经过调整,可以非常便宜地创建短期物体。
答案 2 :(得分:1)