Java字符串的“朝花夕拾”

来源:互联网 发布:tcp端口监听工具 编辑:程序博客网 时间:2024/04/29 11:57
<!--[if !supportEmptyParas]--> <!--[endif]-->
<!--[if !supportEmptyParas]--> <!--[endif]-->
字符串是我们用得很多的一种类,即便是这样,字符串也有很多让我们混淆的地方,还有很多我们不是很清楚的地方。常用的用法,大家都已经烂熟,这里不再重述。只想找出一些平时我们不经意的地方,可能我们已经用过了,但还不是很确定。把它们总结出来,算是“朝花夕拾”吧。
<!--[if !supportEmptyParas]--> <!--[endif]-->
<!--[if !supportLists]-->第一、   <!--[endif]-->关于String对象
关于String对象的问题,每每在bbs上争论不休。
现在倾向的解释是:String s = “abc”;这个语句中s是一个引用,它指向对象”abc”。
这样一来,下面的语句:
String s1 = “abc”;
String s2 = “abc”;
就只产生了一个对象,即:”abc”。
而String s = new String(“abc”);这个语句中s是一个对象。下面的语句:
String s1 = new String(“abc”);
String s2 = new String(“abc”);
就产生了两个对象了,它们是s1和s2。
有了上面的解释,我们就不难理解,为什么我们优先在代码中使用前一种表达方式,因为前一种方式是引用,不论你在代码中要使用多少个相同的引用,只产生一个对象。而后一种方式则即使多个对象的内容一样,它们也是不同的对象,有各自的内存开销;这就大大的增加了我们内存的开销。
同样,下面的代码以及它们的运行结果也就能解释了。
String s1 = "abc";
String s2 = "abc";

String s3 = new String("abc");

代码:
System.out.println(s1==s2);
运行结果:
true
代码:
System.out.println(s1=="abc");
运行结果:
true
代码:
System.out.println(s1.equals(s2));
运行结果:
true
System.out.println(s1==s3);
运行结果:
false
代码:
System.out.println(s3.equals("abc"));
运行结果:
true
<!--[if !supportEmptyParas]--> <!--[endif]-->
<!--[if !supportLists]-->第二、   <!--[endif]-->String与StringBuffer的区别
既然语句:String s = “abc”;中的s是一个引用。那么,在下面的语句:
String s = “abc”;
s = s+”d”;
中,就应该有三个对象:”abc”、”d”和”abcd”。引用s先是指向对象”abc”,后指向对象”abacd”。
这样,我们就能看出String和StringBuffer的区别来。对于下面的代码:
String s = “”;
for(int i=0;i<10;i++)
{

        s = s+i;

}
我们将产生10多个对象。而下面的代码:

StringBuffer sb = new StringBuffer();

for(int i=0;i<10;i++)
{
       sb.append(i);
}
只产生一个对象。
所以,在String对象需要进行相加的时候,使用StringBuffer要明显比使用String优越,特别是在循环相加的时候。
<!--[if !supportEmptyParas]--> <!--[endif]-->
<!--[if !supportLists]-->第三、   <!--[endif]-->其他基本类型与String的转化
在实际的编码过程中,经常要将其他的基本类型转化为String类型,如上面的我们所常用到的例子:
String s = “”;
for(int i=0;i<10;i++)
{

        s = s+i;

}
中,s = s+i;语句中就需要将整型数据i转化为字符串,然后再与s相加。
其实,除了s = s+1;的这种转化方式,还有一种我们大家所不常用到的转化方式,如下:
s = s+Integer.toString(1);
经过大家对对上面两种转化方法所耗时间的测试,结果发现后面一种转化方式所耗的时间大大低于前面一种转化方式所耗的时间。
所以大家在编码的过程中,不妨使用后面的一种转化方式。
<!--[if !supportEmptyParas]--> <!--[endif]-->
<!--[if !supportLists]-->第四、   <!--[endif]-->Object类的toString()的重载
toString()方法是Object类的一个公有方法,Object类是Java所有类的父类。因此,任何其他的Java类都能重写该方法,为己所用。
例如,所有的基本类型的包装类,如:Integer、Float、Double等等,都重写了toString()方法,功能是将该类型转化为String类型。
对toString()的重写一般用来提供一些关于这类的基本信息。如对于一个复数类,如下:

public class Complex

{
        private double real;
        private double image;
        ……
}
它的toString()方法可以写为:

public String toString()

{
        String ri = “”;
       if(this.image<0)
        {
               ri = ri+”-”+Double.toString(Math.abs(this.image))+”i”;
}
else
{
       ri = ri+”+”Double.toString(this.image)+”i”;
}
        return Double.toString(this.real)+ri;
}
上面的这个toString()方法刚好表达了一个复数的数学表达式,这恰恰是我们在对复数做完运算以后希望得到的结果。
又如,对于一个员工类:Employee。我们最常用的、最希望看到的常常是他们的姓名,如下:

public class Employee

{
        private String firstName;
        private String secodeName;
        ……
        public String toString()
        {

               return this.firstName+this.secodeName;

}
……
}
所以,在一些类中,重写toString()方法是很有用的,可能作为显示数据常常使用,也可能用在调试语句中。
<!--[if !supportEmptyParas]--> <!--[endif]-->
<!--[if !supportLists]-->第五、   <!--[endif]-->逃逸字符的问题
逃逸字符的问题是我们在编程过程中经常会遇到的问题。如在HTML编程中遇到“>”或“<”的话,浏览器会将它们作为HTML的保留字符,如标签的开始符和结束符来看待,这样就会出现一些错误。又如在JDBC编程中的sql语句中,如果出现了“””或者“’”等引号字符,也会出错,sql语句会把它们当作一个sql语句的开始或结束符。还有,如URL语句中的“?”等字符,也会造成URL表达式的混乱。等等
遇到了上面的这些情况,我们都自己找一些特殊字符对它们加以替换,然后用完后又替换回来,这些特殊的字符就是逃逸字符。
但是我们自己去找他们的逃逸字符一是比较麻烦,而是容易出错,容易出现把逃逸字符张冠李戴的情况。
鉴于此,Jakarta Commons包为我们提供了一套关于逃逸字符的解决方案,使用这个方案,我们不需要自己亲自去查找逃逸字符,只需要调用Jakarta Commons包的API即可,如下所示:

String s = "There is always < (less) or > (more) than you want.";

String s1 = StringEscapeUtils.escapeHtml(s);

System.out.println(s1);

String s2 = StringEscapeUtils.unescapeHtml(s1);

System.out.println(s2.equals(s));
System.out.println(s2);
输出结果:

There is always &lt; (less) or &gt; (more) than you want.

true

There is always < (less) or > (more) than you want.

是不是很简单,我们只需要在上面的代码中引入Jakarta Commons的相应的包即可。
<!--[if !supportEmptyParas]--> <!--[endif]-->
<!--[if !supportLists]-->第六、   <!--[endif]-->中英文拆字的问题
关于中英文混合句子拆字的问题,是我曾经在bbs上看到的一个同仁的解决方法。觉得很有意思,虽然我到现在也没有用上,但把它放在这篇文章的总结里,算是对字符串的用法的一个收集吧。
我们都知道,Java采用的是Unicode编码,所有的字符都占有一个字,两个字节。那么我们在一个中英文混合的句子中,怎么抽取出来一个个的汉语词语和英语单词呢?
下面就是一个简单的解决方法:
String s = "我是中ab国人";

        byte[] bt = s.getBytes();

        int i=0;

       while(i<bt.length)
        {
               String ss;
               if(bt[i]<0)
               {
                      ss = new String(bt,i,2);
                      i += 2;
               }
               else
               {
                      ss = new String(bt,i,1);
                      i++;
               }
               System.out.println(ss);
        }
<!--[if !supportEmptyParas]--> <!--[endif]-->
输出结果为:
a
b