可以证明,字符串操作是计算机程序设计中最常见的行为
- String不可变
String类中每一个修改String值的方法,实际上都创建了一个新的对象,而原来的对象没有改变
public static void upcase(String s) { return s.toUpperCase(); }
String s = 'aaa';
String ss = upcase(s);
这里upcase只是获取了一份s引用的拷贝,这个引用和原来的s指向同一个对象,s.toUpperCase方法实际上创建了一个新的对象,
方法完成后,方法中的s引用就不存在了
StringBuilder与+
- Java中重载了用于String的+和+=
String mango = "mango";'
String s = "abc" + mango + "def" + 47;
实际上的过程是
StringBuilder tmp = new StringBuilder();
tmp.appen("abc");
tmp.append("mango");
tmp.append("def");
tmp.append(47);
String s = tmp.toString();
如果把这个过程放在一个循环里
String[] str = {"aaa","bbb","ccc"};
String res = "";
for(int i = 0;i < str.length;i++)
res += str[i];
这个过程将变成
for(int i = 0;i < str.length;i++) {
StringBuilder tmp = new StringBuilder();
tmp.append(res);
tmp.append(str[i]);
res = tmp.toString();
}
可以发现res的每一次+=或者=操作,都是相当于创建一个新的StringBuilder对象,并把右值的String一个一个append进去,最后
toString赋值给res
如果直接使用StringBuilder
StringBuilder res = new StringBuilder();
for(int i = 0;i < str.length;i++) {
res.append(str[i]);
}
就只用创建一个StringBuilder对象
所以在循环多的时候,可以尽量使用StringBuilder类
无意识的递归
class A {
public String toString() {
return "InfiniteRecursion " + this; // return "InfiniteRecursion " + this.toString();
}
}
这里的this会被调用toString(),也就陷入了无限递归
- 格式化输出
System.out.format("%d",x);
或者System.out.printf();
类似与C中的printf用法
- Formatter类
所有的格式化功能都由Formatter类实现,当你创建一个Formatter对象的时候,需要向它传递一些信息,告诉它最终的结果要向哪
里输出
Formatter f = new Formatter(System.out);
PrintStrean out = System.out;
Formatter f = new Formatter(out);
这两个都是向System.out输出结果
f.format("%s",s);
像这样输出格式化的结果
- 格式化说明符
%[argument_index$][flags][width][.precision]conversion
默认左对齐,最前面加-表示右对齐
width表示最小尺寸
precision可以表示String的最大位数,或者浮点数的保留位数
- formatter格式转换
d 整数型
c Unicode字符 e 浮点数(科学计数)
b Boolean值 x 整数(十六进制)
s String h 散列码(十六进制)
f 浮点数 % 字符%
- String.format()
这是一个适用于String类的格式化方法,它是一个静态方法,会返回一个格式化以后的String对象,其内部其实也是创建了
Formatter对象