`
hepeng_8
  • 浏览: 81058 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

关于字符串缓冲池的讨论

 
阅读更多

看到一个关于字符串缓冲池的讨论

(转)
大家先来看看一段奇怪的程序:
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();
哇!程序输出:
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();
这样大家都在水池里泡着了 。

import java.*;
import java.io.*;

public class hashcode
{
public static void main(String args [])
{
String o1 = new String("Hello");

String o2 = new String("Hello");

if (o1.equals(o2))
System.out.println("equal"); //equal

System.out.println(o1.hashCode()); //69609650
System.out.println(System.identityHashCode(o1)); //18581223
System.out.println(o2.hashCode()); //69609650
System.out.println(System.identityHashCode(o2)); //3526198

o2 = "hello";

if (!o1.equals(o2))
System.out.println("not equal"); //not equal

System.out.println(o1.hashCode()); //69609650
System.out.println(System.identityHashCode(o1)); //18581223
System.out.println(o2.hashCode()); //99162322
System.out.println(System.identityHashCode(o2)); //7699183

o1 = "Hello";
o2 = "hello";

if (!o1.equals(o2))
System.out.println("not equal"); //not equal

System.out.println(o1.hashCode()); //69609650
System.out.println(System.identityHashCode(o1)); //14285251
System.out.println(o2.hashCode()); //99162322
System.out.println(System.identityHashCode(o2)); //7699183

o1 = "Hello";
o2 = "Hello";

if (o1.equals(o2))
System.out.println("equal");//equal

System.out.println(o1.hashCode());//69609650
System.out.println(System.identityHashCode(o1));//14285251
System.out.println(o2.hashCode());//69609650
System.out.println(System.identityHashCode(o2));//14285251

System.out.println("hello".hashCode()); //99162322
System.out.println("hello".hashCode()); //99162322
System.out.println(System.identityHashCode("hello")); //7699183
System.out.println("Hello".hashCode()); //69609650
System.out.println("Hello".hashCode()); //69609650
System.out.println(System.identityHashCode("Hello")); //14285251

java.lang.System.exit(0);
}
}
分享到:
评论

相关推荐

    第4节: 揭秘JVM字符串常量池和Java堆-01

    第4节: 揭秘JVM字符串常量池和Java堆-01第4节: 揭秘JVM字符串常量池和Java堆-01第4节: 揭秘JVM字符串常量池和Java堆-01第4节: 揭秘JVM字符串常量池和Java堆-01第4节: 揭秘JVM字符串常量池和Java堆-01第4节: ...

    C#字符串删除指定字符串|字符串删除子字符串

    C#字符串删除指定字符串|C#字符串删除子字符串

    java 字符串转16进制 16进制转字符串 将两个ASCII字符合成一个字节;

    java 字符串转16进制 16进制转字符串 将两个ASCII字符合成一个字节; java 字符串转16进制 16进制转字符串 将两个ASCII字符合成一个字节; java 字符串转16进制 16进制转字符串 将两个ASCII字符合成一个字节; java ...

    rf.rar_RF 字符串截取_Rf字符串比较_rf字符串切割

    一个关于字符串匹配的算法,已经经过编译,希望对你有帮助

    使用一个字符串分割另一个字符串

    * 使用一个字符串分割另一个字符串 * * @param delimiter 边界上的分隔字符 * @param haystack 输入的字符串 * @param out 输出的字符串指针 * @return 分割成了多少个成员 */ int explode(char *delimiter, ...

    关于字符串包含的问题

    第一节、一道俩个字符串是否包含的问题 1.1、O(n*m)的轮询方法 1.2、O(mlogm)+O(nlogn)+O(m+n)的排序方法 1.3、O(n+m)的计数排序方法 第二节 2.1、O(n+m)的hashtable的方法 2.2、O(n+m)的数组存储方法 ...

    字符串的对比与替换

    编写程序:从键盘上输入一个包含10个字符的字符串,把该字符串与程序中给定的字符串("bacdbcabca") //依次比较,统计两个字符串对应字符相等的数目。然后输出从键盘上输入的字符串, //并把两个字符串中对应字符不...

    C++字符串中检测特定的字符串

    C++ 语言中关于字符串编程。字符串中查找字符串。。。。

    c#正则表达式截取指定字符串之间的字符串。类文件直接用就可以了~

    给写了2个方法,一个是直接截取单个需要的字符串,比如字符串string a="ab123456",我只需要提取3,那么就是单独截取就可以了,从2开始到4结束就行。 第二个是把所有的符合条件的字符串都截取出来,提取出来,比如...

    关于字符串相等的比较

    字符串比较除了代码中的方法还有哪些方法更好的描述。

    C语言字符串拆分成字符串数组.c

    纯C语言实现字符串拆分操作,把字符串拆分成字符串数组,然后再输出。 使用sstream方法,作为底层驱动操作实现非常方便。

    字符串公共字符串(C++)

    求两个字符串的最长公共字符串 输出全部位置信息,并输出字符串,相同字符串先输出所有位置信息在输出字符串 测试平台:XP/VS 2008 CN

    JS中判断某个字符串是否包含另一个字符串的五种方法

    indexOf() 方法可返回某个指定的字符串值在字符串中首次出现的位置。如果要检索的字符串值没有出现,则该方法返回 -1。 方法二:match() var str = "123" var reg = RegExp(/3/); if(str.match(reg)){ //包含; } ...

    封装一个,完善字符串,字符串

     必须实现如下操作,字符串比较、求串的长度、判断串是否为空、将串置空、字符串赋值(包括两个字符串类复制,一个字符串赋值到CmyString对象)、求字符串中的一个字符或改变字符串中的一个字符(采用重载[]),...

    字符串 介绍 字符串 介绍

    字符串 介绍 字符串 介绍 字符串 介绍 字符串 介绍

    易语言字符串操作

    易语言字符串操作源码,字符串操作,字符串_取长度,字符串_取中间,字符串_取左边,字符串_取右边,字符串_替换,到宽字符,到多字节,取文本数据地址,取字节集数据地址,MultiByteToWideChar,WideCharToMultiByte

    微机原理课设字符串动画.docx

    1、菜单 内容包括:①输入字符串;②字符串动画显示;③退出. 2、输入字符串 选择该项后,可以输入一个字符串.该字符串即为动画显示时所显示的字符串. 3、字符串动画显示 显示字符串在一矩形框内从无到有,按指定方向...

    输入一个字符串参数,返回反序字符串

    输入一个字符串参数,返回该字符串的反序字符串

    详解C++ string常用截取字符串方法

    string常用截取字符串方法有很多,但是配合使用以下两种,基本都能满足要求: find(string strSub, npos); find_last_of(string strSub, npos); 其中strSub是需要寻找的子字符串,npos为查找起始位置。找到返回子...

    PB POWERBUILDER 字符串 数组 相互 转换 转化

    |PowerBuilder 数组字符串相互转化 天津 李华锋 * * | | * *PowerBuilder 数组字符串相互转化 完全免费 * * | | * *如果你将这个程序放在你的网站上,我希望你能同时加上本站的链接 | | * | * | * *老字符串转数组...

Global site tag (gtag.js) - Google Analytics