String
String不是简单类型,而是一个类,它被用来表示字符序列。他有两种基本的初始化方式。
String s1="abc";
String s2= new String("abc");
字符串的比较:
System.out.println(s1==s2);
或者:
System.out.println(s1.equals(s2));
String对象是不可变的,在String勒种每一个看起来会修改String对象聂彤的方法,实质都是创建了一个新的对象。
String作为参数传递的特点:传引用,但通过形参引用并未改变实参指向的字符串内容。
public class Str {
public static void change(String a){
a = a+"a";
}
public static void main(String[] str){
String s= "abc";
Str.change(s);
System.out.println(s);
s = s+"abc";
System.out.println(s);
}
}
运行结果为:abc abcabc
由此可见,尽管是传引用,但通过形参引用并未改变实参指向的字符串内容
字符串中某个字符的替换,用到replace方法
String s1= new String("abc");
s1 = s1.replace("a","A");
字符串的拼接用到concat方法
String s1= new String("abc");
s1 = s1.concat("def");
replace方法源代码
public String replace(char oldChar, char newChar) {
if (oldChar != newChar) {
int len = value.length;
int i = -1;
char[] val = value;
while (++i < len) {
if (val[i] == oldChar) {
break;
}
}
if (i < len) {
char buf[] = new char[len];
for (int j = 0; j < i; j++) {
buf[j] = val[j];
}
while (i < len) {
char c = val[i];
buf[i] = (c == oldChar) ? newChar : c;
i++;
}
return new String(buf, true);//创建新的对象
}
}
return this;
}
concat源代码
public String replace(char oldChar, char newChar) {
if (oldChar != newChar) {
int len = value.length;
int i = -1;
char[] val = value;
while (++i < len) {
if (val[i] == oldChar) {
break;
}
}
if (i < len) {
char buf[] = new char[len];
for (int j = 0; j < i; j++) {
buf[j] = val[j];
}
while (i < len) {
char c = val[i];
buf[i] = (c == oldChar) ? newChar : c;
i++;
}
return new String(buf, true);//创建新的对象
}
}
return this;
}
为什么String被设计成不可变性(immutable)?
1. 字符串常量池的需要.多个String引用可共享同一对象,节省内存空间.
2.String哈希码的唯一性,可缓存。String可以作为HashMap键值,高效。
3.String多线程安全
4.String常作为参数传递(网络,数据库,安全性)
StringBuffer
StiringBuffer与String的区别:
String是不变的,但StringBuffer是可变的。同时StringBuffer通过形参引用会改变实参指向的字符串内容。并且增加,插入,修改,删除等操作不需要多次创建新的对象,比String更高效
public static void change(StringBuffer s){
s = s.append("abc");
}
public static void main(String[] str){
StringBuffer s = new StringBuffer("abc");
change(s);
System.out.println(s);
}
结果为abcabc
StirngBuffer的append方法,作用是字符串的增加
public static void main(String[] str){
StringBuffer s = new StringBuffer("abc");
s.append("def");
System.out.println(s);
}
运行结果为abcdef
public class StringBufferModify{
public static void main (String [] args) {
StringBuffer a = new StringBuffer ("A");
StringBuffer b = new StringBuffer ("B");
operate(a,b);
System.out.println(a + "," +b);
}
static void operate(StringBuffer x, StringBuffer y) {
x.append(y);
y = x;
}
}
运行结果:AB,B
StingBulider
JDK5 引入了StringBuilder,其与StringBuffer的 API兼容, 性能比StringBuffer更高,但不是线程安全的。
String s = “a”; s = s + “b”; // 编译器会转化为下述语句
String st = new StringBuilder("a").append("b").toString();
String字符串拼接:
String s = "a";
for(int i=0; i<10000;i++){
s = s + “b” ; //编译器会进行优化,但此种写法仍然效率低下,循环体内每次
需要产生StringBuilder对象
StringBulider字符串拼接:
StringBuilder st = new StringBuilder("a"); //效率较高,只需新建一个对象
for(int i=0; i<10000;i++){
st.append(“b");
}
字符串拼接,应使用StringBuilder或StringBuffer,并将对象创建语句放到 循环体外
String,StirngBuffer,StringBuilder比较:
String,StringBuffer,StringBuilder的相同点
1.内部实现基于字符数组,封装了对字符串处理的各种操作
2. 可自动检测数组越界等运行时异常
String、StringBuffer、StringBuilder不同点
1. String内部实现基于常量字符数组,内容不可变;StringBuffer、StringBuilder基于普通字符数组,数组大小可根据字符串的实际长度自动扩容,内容可变。
2.性能方面,对于字符串的处理,相对来说StringBuilder > StringBuffer > String
3.StringBuffer线程安全;StringBuilder非线程安全