我正在从二进制文件中读取数据,并希望将字节转换为美国 ASCII 字符串。有没有什么方法可以在不调用 String
上的 new
的情况下避免在字符串文字池中创建多个语义相等的 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();
最佳答案
您必须有一个将字节数组映射到字符串的缓存,然后在创建新字符串之前在缓存中搜索任何相等的值。
您可以使用 intern()
实习现有的字符串正如 Yishai 发布的那样 - 这不会阻止您创建更多字符串,但它会使除了第一个(对于任何字符序列)之外的所有字符串都非常短暂。另一方面,它会使所有不同的字符串确实存在很长时间。
您可以使用 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 已经过调整,可以非常便宜地创建短期对象。
关于java - 使用特定字符集将 byte[] 转换为 String 时避免创建 'new' String 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1578417/