`
chenshuyi
  • 浏览: 29348 次
文章分类
社区版块
存档分类
最新评论

字符串缓冲池

 
阅读更多
看到一个关于字符串缓冲池的讨论

(转)
大家先来看看一段奇怪的程序:
public class TestString {
public static void main(String[] args) {
String s1 = "Monday";
String s2 = "Monday";
}
}
这个程序真是简单啊!可是有什么问题呢?

1. 来自 String 的忧虑
上面这段程序中,到底有几个对象呢?
可能很多人脱口而出:两个,s1 和 s2
为什么?
String 是 final 类,它的值不可变。
看起来似乎很有道理,那么来检测一下吧,稍微改动一下程序
就可以看到结果了:

public class TestString {
public static void main(String[] args) {
String s1 = "Monday";
String s2 = "Monday";
if (s1 == s2)
System.out.println("s1 == s2");
else
System.out.println("s1 != s2");
}
}
呵呵,很多人都会说已经不止两个对象了
编译并运行程序,输出:s1 == s2
啊!
为什么 s1 == s2 ?
== 分明是在说:s1 与 s2 引用同一个 String 对象 -- "Monday"!

2. 千变万化的 String
再稍微改动一下程序,会有更奇怪的发现:
public class TestString {
public static void main(String[] args) {
String s1 = "Monday";
String s2 = new String("Monday");
if (s1 == s2)
System.out.println("s1 == s2");
else
System.out.println("s1 != s2");
if (s1.equals(s2))
System.out.println("s1 equals s2");
else
System.out.println("s1 not equals s2");
}
}
我们将 s2 用 new 操作符创建
程序输出:
s1 != s2
s1 equals s2
嗯,很明显嘛
s1 s2分别引用了两个"Monday"String对象
可是为什么两段程序不一样呢?

3. 在 String 的游泳池中游泳
哈哈,翻了翻书终于找到了答案:
原来,程序在运行的时候会创建一个字符串缓冲池
当使用 s2 = "Monday" 这样的表达是创建字符串的时候,程序首先会
在这个String缓冲池中寻找相同值的对象,在第一个程序中,s1先被
放到了池中,所以在s2被创建的时候,程序找到了具有相同值的 s1
将 s2 引用 s1 所引用的对象"Monday"

第二段程序中,使用了 new 操作符,他明白的告诉程序:
“我要一个新的!不要旧的!”与是一个新的"Monday"Sting对象被创
建在内存中。他们的值相同,但是位置不同,一个在池中游泳
一个在岸边休息。哎呀,真是资源浪费,明明是一样的非要分开做什么呢?

4. 继续潜水
再次更改程序:
public class TestString {
public static void main(String[] args) {
String s1 = "Monday";
String s2 = new String("Monday");
s2 = s2.intern();
if (s1 == s2)
System.out.println("s1 == s2");
else
System.out.println("s1 != s2");
if (s1.equals(s2))
System.out.println("s1 equals s2");
else
System.out.println("s1 not equals s2");
}
}

这次加入:s2 = s2.intern();

补充:

当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(用 equals(Object) 方法确定),则返回池中的字符串。否则,将此 String 对象添加到池中,并返回此 String 对象的引用。 用intern可以提高堆内存的利用率。

哇!程序输出:
s1 == s2
s1 equals s2
原来,程序新建了 s2 之后,又用intern()把他打翻在了池里
哈哈,这次 s2 和 s1 有引用了同样的对象了
我们成功的减少了内存的占用

5. == 与 equals() 的争斗
String 是个对象,要对比两个不同的String对象的值是否相同
明显的要用到 equals() 这个方法
可是如果程序里面有那么多的String对象,有那么多次的要用到 equals ,
哦,天哪,真慢啊
更好的办法:
把所有的String都intern()到缓冲池去吧
最好在用到new的时候就进行这个操作
String s2 = new String("Monday").intern();
这样大家都在水池里泡着了 。
分享到:
评论

相关推荐

    面试常见问题-Java

    * 当创建一个字符串时,Java 会在字符串缓冲池中查找是否有相同的字符串常量,如果存在直接返回其引用 * 使用 intern() 方法可以将字符串添加到缓冲池中 * 字符串缓冲池可以减少内存的使用,但是也可能会导致内存...

    JAVA中equals和的区别.doc

    - 如果字符串缓冲池中没有与当前`String`对象等价的字符串,则将当前`String`对象添加到字符串缓冲池中,并返回该缓冲池中的引用。 - 如果字符串缓冲池中已经有了等价的字符串,则返回缓冲池中该字符串的引用。 ...

    java中equals和==的区别.docx

    在这个例子中,s1 和 s2 都是字符串 "Monday",但是 s1 引用的是字符串缓冲池中的对象,而 s2 引用的是一个新的字符串对象。 intern() 方法 Java 中的 intern() 方法用于将字符串对象添加到字符串缓冲池中。intern...

    java中equals和==的区别.pdf

    - 使用 `new` 创建 String 对象时,会在堆内存中创建一个新的实例,不会从字符串缓冲池中查找。 3. **intern() 方法** - `String` 类的 `intern()` 方法会检查字符串池中是否存在具有相同内容的字符串。如果存在...

    java中equals和==的区别

    当使用字面量创建 String 对象时,Java 会首先在字符串缓冲池中寻找具有相同值的对象,如果找到,则返回该对象的引用;否则,创建一个新的 String 对象。 在第一个例子中,我们创建了两个 String 对象 s1 和 s2,...

    java中equals和==的比较.pdf

    这是因为字符串字面量在运行时会被放入字符串缓冲池,以优化内存使用和提高性能。 2. 如果一个字符串是通过 `new String("Monday")` 创建的,那么它会在堆上创建一个新的对象,即使内容与常量池中的字符串相同。...

    如何生成快速大量字符串并且比较是否包含某个字符串

    使用`using`语句或`IDisposable`接口及时释放不再需要的对象,以及合理设置缓冲池大小。 7. **字符串池**:C#有内置的字符串池,可以优化短字符串的创建和销毁。但对长字符串或大量字符串,可能需要手动管理。 ...

    字符串处理文档

    11. **字符串缓冲区** `StringBuffer`和`StringBuilder`是线程安全和非线程安全的可变字符串容器,适用于大量字符串操作。在多线程环境中,推荐使用`StringBuffer`;否则,`StringBuilder`效率更高。 12. **字符串...

    java中equals和==的区别.doc

    在 Java 中,还有一个字符串缓冲池的概念。当我们使用字符串常量时,Java 会在缓冲池中查找相同值的对象,如果找到了,那么将返回该对象的引用。如果没有找到,那么将创建一个新的字符串对象。 因此,在上面的代码...

    string_字符串_

    此外,为了提高效率,可能会采用缓冲池技术来减少内存碎片。 总的来说,这个自定义的`XString`类和`XStringUtil`工具类提供了更丰富的字符串处理功能,旨在简化开发者的代码,提高程序的可读性和效率。通过深入理解...

    java中equals和==的区别文.pdf

    3. 在字符串缓冲池的概念下,`intern()` 方法可以帮助我们避免不必要的对象创建。如果一个 `String` 已经存在于池中,`intern()` 方法会返回池中的引用。所以,当我们调用 `s2.intern()`,`s2` 会被更新为池中对应的...

    51单片机串口程序(带缓冲区)

    - `send_string_com` 函数用于发送字符串,需要指定字符串长度。 3. **接收功能**: - 定义了一个中断服务函数 `serial()`,用于处理接收到的数据。 - 接收的数据被存放在定义好的缓冲区 `inbuf1` 中,并进行...

    字符串处理函数.zip

    同时,合理使用字符串池和内存分配策略可以提升程序效率。 总的来说,理解和熟练掌握字符串处理函数是每个程序员的基本功,无论是进行数据解析、日志记录,还是构建复杂的文本算法,这些函数都起着关键作用。通过...

    JAVA字符串中所用的方法.rar

    11. **字符串缓冲区** - `StringBuilder` 和 `StringBuffer`: 动态增长的字符串容器,支持插入、删除和替换操作,适合大量字符串操作。 12. **Unicode编码** - `codePointAt(int index)` 和 `codePointBefore(int...

    java中equals和的比较.doc

    在 Java 中,还有一个特殊的字符串缓冲池。当我们使用字符串字面值创建字符串对象时,Java 会首先在这个缓冲池中寻找相同值的对象。如果找到,就返回该对象的引用;否则,创建一个新的字符串对象。 让我们继续修改...

    第8章 枚举,字符串和数组.ppt

    例如,`append(String str)`方法用于向字符串缓冲区追加字符串,`insert(int offset, String str)`方法在指定位置插入字符串,最后`toString()`方法将字符串缓冲区的内容转换为字符串形式。 数组是Java中存储一组...

    传智播客java_web视频教程笔记全套

    - Java提供了一个字符串缓冲池以优化字符串操作。 - 面试题示例: - `String s = "abc"`与`String s = new String("abc")`的区别。 - `String s = "a" + "b" + "c" + "d"`创建了几个对象? - `String s1 = "a";...

Global site tag (gtag.js) - Google Analytics