String类详解
String表示字符串,Java中所有的字面量都是String类的实例,如“abc”。字符串是常量,在定义以后就不能修改了。因为字符串是不可变的,所以可以共享它们。
String str=”abc”;
相当于
char data[ ] = {‘a’,’b’,’c’};
String str = new String (data) ;
定义
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {}
从该类的声明中可以看出,String是final类型的,是不可以被继承的,它实现了java.io.Serializable、Comparable 、CharSequence
属性
private final char value[];
这是一个字符数组,并且是final类型,它用来存储字符串内容,即String的内容一旦确定就不能更改了。
private int hash;
缓冲字符串的hash Code,默认值为0
private static final long serialVersionUID = - 6849794470754667710L;
private static final ObjectStreamField[] serialPersistentFields =
new ObjectStreamField[0];
构造方法
String类有很多重载的构造方法。
1. 使用字符数组、字符串构造一个String
- String是使用字符数组(char[])实现的。
- 当我们使用字符数组创建字符串时,会用Arrays.copyOf方法和Arrays.copyOfRange方法。这两个方法是将原有的字符数组中的内容逐一的复制到String中字符数组中。
- 当我们使用字符串创建数组时,直接将源String的value和hash两个属性赋值给目标String。因为String一旦定以后是不可改变的,所以也就不用担心改变源String的值会影响到目标String。
public String(char value[]) {
this.value = Arrays.copyOf(value, value.length);
}
public String(String original) {
this.value = original.value;
this.hash = original.hash;
}
2 使用字节数组构造一个String
在Java中,char[ ]数组是以Unicode码来保存的。String和char是内存形式,byte是网络传输或存储的形式。在传输和存储的过程中需要报byte[ ] 和String相互转换。此外,为了保证转换的过程中不出现乱码,需要指定编码。
public String(byte bytes[], int offset, int length, Charset charset) {
if (charset == null)
throw new NullPointerException("charset");
checkBounds(bytes, offset, length);
this.value = StringCoding.decode(charset, bytes, offset, length);
}
3 使用StringBuffer和StringBuilder构造一个String
这两者也可以用来构建String,但是很少用。可以调用他toString方法直接转化为String。这个方法特点是复制参数的value给String的value;
public String(StringBuffer buffer) {
synchronized(buffer) {
this.value = Arrays.copyOf(buffer.getValue(), buffer.length());
}
}
public String(StringBuilder builder) {
this.value = Arrays.copyOf(builder.getValue(), builder.length());
}
4 一个特殊的保护类型的构造方法
这个方法和String(char[ ] value)方法很类似。参数share在实际中并没用到,只是起到与区分的作用。这个方法为protected方法,在外面无法访问,防止破坏字符串的不变性。
优点:性能好;节约内存
缺点:容易内存泄露
使用该构造函数的方法有:concat()、replace()、valueOf(char c)
String(char[] value, boolean share) {
// assert share : "unshared not supported";
this.value = value;
}
常用方法
length()返回字符串长度
isEmpty()返回字符串是否为空
charAt(int index)返回字符串中第(index+1)个字符串
char[ ] toCharArray()转化为字符数组
trim()去掉两端空格
toUpperCase()转化为大写
toLowerCase()转化为小写
String concat(String)
拼接字符串,使用了特殊的构造函数
public String concat(String str) {
int otherLen = str.length();
if (otherLen == 0) {
return this;
}
int len = value.length;
char buf[] = Arrays.copyOf(value, len + otherLen);
str.getChars(buf, len);
return new String(buf, true);
}
String replace (char,char)
replaceAll()和replaceFirst()两者与replace的区别在于,这两者可以基于规则表达式进行操作。
替换字符串,使用了特殊的构造函数
public String replace(char oldChar, char newChar) {
if (oldChar != newChar) {
int len = value.length;
int i = -1;
char[] val = value; /* avoid getfield opcode */
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 [ ] split(String regex,int limit)
String [ ] split(String regex)
按照字符regex将字符串分割程limit份
比较方法
用来比较两个字符串的关系
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String) anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
HashCode方法
属性中有个hash值,该方法是用来计算hash值的。它的实现是通过数学公式来完成的。
s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
subString方法
subString方法是用来从字符串中截取想要的内容,它的实现是是通过 new String(value,int,int)来创建新的字符串。
java7以后不在使用那个特殊的构造方式来创建字符串。
public String substring(int beginIndex) {
if (beginIndex < 0) {
throw new StringIndexOutOfBoundsException(beginIndex);
}
int subLen = value.length - beginIndex;
if (subLen < 0) {
throw new StringIndexOutOfBoundsException(subLen);
}
return (beginIndex == 0) ? this : new String(value, beginIndex, subLen);
}
copyValueOf和valueOf方法
现在的语法中,两者没有区别,都是通过创建新的字符串。
public static String valueOf(boolean b) {
return b ? "true" : "false";
}
public static String valueOf(char data[]) {
return new String(data);
}
public static String valueOf(char c) { //c 是字符 不是字符数组
char data[] = {c};
return new String(data, true);
}
public static String valueOf(int i) {
return Integer.toString(i);
}
public static String valueOf(long l) {
return Long.toString(l);
}
public static String valueOf(float f) {
return Float.toString(f);
}
public static String valueOf(double d) {
return Double.toString(d);
}
intern()方法
该方法返回一个字符串对象的
String对“+”的重载
String的“+”是唯一一个重载运算符。
String s1 = "Hollis";
String s2 = "Chuang";
String s3 = s1 + s2;
String s4 = "Hollis" + "Chuang";
String s1 = "Hollis";
String s2 = "Chuang";
String s3 = (new StringBuilder()).append(s1).append(s2).toString();
String s4 = "HollisChuang";