一、String类
- 初始化
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
//数组定义为常量,不可修改
private final char value[];
public String() {
this.value = "".value;
}
- 实例化字符串
// //实例化字符串(传入字符串)
public String(String original) {
this.value = original.value;
this.hash = original.hash;
}
//字符数组的实例化构造方法(传入字符数组)
public String(char value[]) {
this.value = Arrays.copyOf(value, value.length);
}
- 判断两个字符串是否相等(在string中重写了equals的方法,object的equals方法相当于“==”)
//判断两个字符串是否相等
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
//判断是不是String类型
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;
}
//重写equals时需要重写hashCode方法
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}
注意:在重写equals()时也必须要重写hashCode()方法,以保证相同对象的hash值也是一样的,否则会出现意想不到的问题的。因为如果我们对一个对象重写了equals,意思是只要对象的成员变量值都相等那么equals就等于true,但不重写hashcode,那么我们再new一个新的对象, 当原对象.equals(新对象)等于true时,两者的hashcode却是不一样的,由此将产生了理解的不一致,导致混淆
二、字符串的三种拼接方法
① 加号
② concat方法
③ append方法
代码案例
public class StringConnect {
public static void main(String[] args) {
String str = "a";
long time = System.currentTimeMillis();
for (int i = 0; i < 10000; i++) {
str += "c";
}
System.out.println("加号所花费的时间:");
System.out.println(System.currentTimeMillis()-time);
String str2 = "a";
time = System.currentTimeMillis();
for (int i = 0; i < 10000; i++) {
str2.concat("c");
}
System.out.println("cancat方法所花费的时间:");
System.out.println(System.currentTimeMillis()-time);
time = System.currentTimeMillis();
StringBuilder stringBuilder = new StringBuilder("a");
for (int i = 0; i < 10000; i++) {
stringBuilder.append("c");
}
String str3 = stringBuilder.toString();
System.out.println("StringBuilder的append方法:");
System.out.println(System.currentTimeMillis()-time);
}
}
输出结果:
主要的部分字节码如下:
0 ldc <String "a"> [16]
2 astore_1 [str]
3 invokestatic java.lang.System.currentTimeMillis() : long [18]
6 lstore_2 [time]
7 iconst_0
8 istore 4 [i]
10 goto 36
13 new java.lang.StringBuilder [24]
16 dup
17 aload_1 [str]
18 invokestatic java.lang.String.valueOf(java.lang.Object) : java.lang.String [26]
21 invokespecial java.lang.StringBuilder(java.lang.String) [32]
24 ldc <String "c"> [35]
26 invokevirtual java.lang.StringBuilder.append(java.lang.String) : java.lang.StringBuilder [37]
29 invokevirtual java.lang.StringBuilder.toString() : java.lang.String [41]
结论:append方法最快、concat次之、加号最慢
- 1.当使用+进行多个字符串连接时,实际上是产生了一个StringBuilder对象和一个String对象。
- 2.每次concat操作都会创建一个新的String对象,限制速度
- 3.整个方法内并没有生成对象。只是最后toString返回一个对象