字符串拼接方法和效率问题

一、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);

}

}

```

输出结果:

![输出结果](https://img-blog.csdnimg.cn/20190317131429885.png)

主要的部分字节码如下:

```

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返回一个对象

原文链接:,转发请注明来源!