使用特定字符集将 byte[] 转换为 String 时,避免创建“新”String 对象

vah*_*idg 5 java string pool character-encoding

我正在读取一个二进制文件并希望将字节转换为美国 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();
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 3

您必须有一个将字节数组映射到字符串的缓存,然后在创建新字符串之前在缓存中搜索任何相等的值。

您可以使用 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;
Run Code Online (Sandbox Code Playgroud)

您甚至可以付出更多的努力,最终得到一个 LRU 缓存,这样它将保留 N 个最近获取的字符串,并在需要时丢弃其他字符串。

正如我所说,这些都不会减少首先创建的字符串数量 - 但这在您的情况下可能是一个问题吗?GC 经过调整,可以非常便宜地创建短寿命对象。