C语言中字符串的工作方式:字符串由系列字节组成,后跟一个取值为0的空字符,这里很明确地表明了两点:
(1)如果不遍历字符串并查到末尾的空字符串,就没有办法知道字符串在何处结束
(2)字符串中不能包含任何零。因此,C字符串中不能存放诸如JPEG图片之类的任何二进制数据块。
为什么是这样?那是因为在上面开发了UNIX与C程序设计语言微处理器有一种ASCIZ字符串类型。ASCIZ的中文意思是“末尾有一个零的ASCII”
这样存放字符串方式非常糟糕,就像Shlemiel算法
而Pascal语言通过将过字符串的首字节用于存放字节个数,对该问题加以解决。
C语言两个函数
(1)strcat() 像Shlemiel算法
(2)malloc()类似于动态分区分配,提高性能的方法总是分配大小为2的幂的内存块,这样做最大限度地减少进入空闲链的怪异的片段的数量。
Java字符串,就是这个神秘的String,是对象,可是只有对象的一部分特性,是基本类型,可是操作起来不太像基本类型,
看几个古怪的例子:
//String 不可变,试图对String更新都会重新生成
String sa = new String("a"); String sa = new String("a");
String sb = sa; //引用赋值,指向同一个对象 String sb = sa;
System.out.println(sa == sb); //结果为true sa = "a"; //常量池赋值,指向常量池的地址,sa不指向堆地址
System.out.println(sa == sb); //结果为false
String sa = "a"; String sa = "a";
String sb = "b"; String sb = "b";
String sc = "ab"; String sc = "ab";
String sd = "a" + "b"; //在常量池操作 String sd = sa + sb; //不在常量操作,在堆里边操作
System.out.println(sd == sc); //结果为true System.out.println(sd == sc); //结果为false
//StringBuffer与StringBuilder是可变字符串
讨论String和StringBuffer可不可变。本质指对象内部的value[]字符数组可不可变,而不是对象引用可不可变
StringBuffer与StringBuilder的线程安全性问题
StringBuffer和StringBuilder可以算是双胞胎了,这两者的方法没有很大区别。只有一点例外:在源代码中StringBuffer的很多方法都被关键字synchronized 修饰了,而 StringBuilder没有。
镜头总结: (1) 在编译阶段就能够确定的字符串常量,完全没有必要创建String或StringBuffer对象。直接使用字符串常量的"+"连接操作效率最高。(2)否则,StringBuffer对象的append效率要高于String对象的"+"连接操作。
(3) intern()方法很有用。
当调用String 对象的intern方法时,如果池已经包含一个等于此对象的字符串(用 equals(Object) 方法确定),则返回池中的字符串。否则,将此 String 对象添加到池中,并返回此 String 对象的引用。
也就是如果我们需要使用new关键字来创建很多内容重复的字符串的话,使用String.intern()方法可以提高效率。
浙公网安备 33010602011771号