Java 避免创建';新';使用特定字符集将字节[]转换为字符串时的字符串对象
我正在读取一个二进制文件,想把字节转换成ASCII字符串。有没有办法在不调用Java 避免创建';新';使用特定字符集将字节[]转换为字符串时的字符串对象,java,string,character-encoding,pool,Java,String,Character Encoding,Pool,我正在读取一个二进制文件,想把字节转换成ASCII字符串。有没有办法在不调用String上的new的情况下执行此操作,以避免在字符串文本池中创建多个语义相同的String对象?我认为这可能是不可能的,因为这里不可能引入使用双引号的String对象。这是正确的吗 private String nextString(DataInputStream dis, int size) throws IOException { byte[] bytesHolder = new byte[size];
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()方法,以确保整个JVM都有一个intern()方法
String s = new String(bytes, "US-ASCII").intern();
您不会避免再次创建初始字符串,但会在存储上保存
也就是说,插入字符串的存储空间有限,因此请谨慎使用。更好的选择可能是使用字符串作为键和值实现HashMap,并检查字符串是否已经存在,如果已经存在则获取它,如果不存在则插入它。这样就不会有这样的内存限制。必须有一个缓存将字节数组映射到字符串,然后在创建新字符串之前在缓存中搜索任何相等的值 您可以使用Yishai发布的
intern()
插入现有字符串-这不会阻止您创建更多字符串,但会使除第一个字符串(对于任何字符序列)外的所有字符串都非常短暂。另一方面,它将使所有不同的字符串确实存在很长时间
您可以使用映射进行“伪实习”:
您甚至可以投入更多的精力,最终得到一个LRU缓存,这样它将保留N个最近获取的字符串,在需要时丢弃其他字符串
正如我所说,所有这些都不会减少最初创建的字符串的数量,但这在您的情况下可能是个问题吗?GCs已经过调整,使得创建短期对象的成本非常低。除非您分析了应用程序并确定创建的字符串是问题的确切根源,否则您不应该担心它
如果您发现字符串
的创建是您问题的根源,我会推荐您的建议,即从字节[]
到字符串
的映射。这与您的字符串
的效果大致相同,但在重新启动VM之前不会占用宝贵的内存。如果要对它们进行垃圾收集,则调用“new”不是问题,我更关心池中字符串的数量。但你说得对,使用intern()时,他们可能太“长寿”。想一想。啊,我不知道实习生()。我会去实习,看看是否值得。没有“普通对象池”。你在说什么?@erickson:我是说JVM的堆和字符串文本池。
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;