2.当我们使用了‘+’,‘+=’操作符,例如
Stingmango = “mango”;
Strings = “abc” + mango + “def” + 47;
看下面两个方法:
public class TestStringBuilder {
public String A(String[] fields){
String result = "";
for(int i = 0; i < fields.length; i++){
result += fields[i];
}
return result;
}
public String B(String[] fields){
StringBuilder result = new StringBuilder();
for(int i = 0; i < fields.length; i++){
result.append(fields[i]);
}
return fields.toString();
}
}
两个方法虽然实现了同样的功能,但是在效率上却是完全不一样的。对于第一个方法A,不难理解,每次循环都会创建一个StringBuilder对象,然后在在调用两次append()方法。而对于第二个方法B,由于在循环体前面就已经创建了StringBuilder对象,所以在循环体里不会在创建StringBuilder对象。显然,对于这种情况,
请看下面一个方法(有关字符串效率操作):
public String C(String[] key, String[] value){StringBuilder result = new StringBuilder();for(int i = 0; i < key.length && i < value.length; i++){result.append(key[i]);result.append(":");result.append(value[i]);result.append(“,”);}return result.toString();
}
对于这个方法,每次循环都会调用四次append()方法,一点点着把key与value拼接起来。可能有人会觉得太麻烦,想走捷径,例如这样写:append(key[i] + “:”+ value[i] + “,”);如果这样写,编译器在处理的时候就会为另外创建一个StringBuilder对象来处理括号内的字符串操作,显然,这种方法最终还是会调用四次append()方法,而且还另外创建了一个StringBuilder对象,效率低。
无意识的递归:
java中的类从根本上都是继承自Object,标准容器类自然也不例外。因此容器类都有toString()方法,并且覆写了该方法,使得它生成的Sting结果能够表达容器自身,以及容器所包含的对象,例如当你调用ArrayList.toString()时,它会遍历ArrayList中包含的所有对象,并且调用每个元素的toString方法。
考虑下面一个问题:如果你希望用toString()方法打印出对象的内存地址,也许你会考虑使用this关键字:
public class Student {
@Override
public String toString() {
return "student address:" + this + "\n";
}
public static void main(String[] args) {
List<Student> list = new ArrayList<>();
for(int i = 0; i < 10; i++){
list.add(new Student());
}
System.out.println(list);
}
}
当年执行这段程序的时候,你会发现这段程序抛出一段非常长的异常。为什么会这样呢?实际上,当你运行
“studentaddress:” + this + “\n”
这句代码时,发生了类型转换,由Student类型(this)转成String类型,那它是怎么转换的呢?实际上,当编译器看到一个String对象后面跟着一个“+”,而在后面的对象不是String时,编译器就会试着调用该对象的toString()方法把它变成String对象,也就是调用了this.toString(),于是,就发生了递归调用。