String 的”+”和 StringBuilder
String 是不可变的字符串对象,”+” 连接两个字符串,实际上是创建了一个新的 String 对象,以包含修改后的字符串内容,最初的那个Sring没有改变…“+” 实际上是编译器创建了一个StringBuilder,用来构造最终的String,每个字符串都会调用一次StringBuilder 的 appender()方法。虽然String 的“+”操作实际上是用StringBuilde.appender()但是
String str = "123";
String str2 = "abc"+ str + "def" + "xyz";
System.Out.Println(str2);
//str2====: abc123defxyz
会生成一个新的String包含”abc”和 str 相连(“abc123”),这个新对象再与”def”相连(“abc123def”),再生成一个新对象和”xyz”相连(“abc123defxyz”)最终生成str2,中间会生成多个临时对象,之后还要被垃圾回收器清理掉.
无意识递归
public class TestString {
public String toString() {
return "address : " + this;
}
}
这个方法是希望返回一个对象的地址字符串。
return 中字符串的”+” 操作会把后面的this转换为字符串,如何转换?当然是this本类的toString,这就会形成递归调用。这里应该使用super.toString,这样就是用Object的toString方法.
String的格式化输出
public class Turtle {
private String name;
private Formatter formatter;
public Turtle(String name,Formatter formatter) {
this.name = name;
this.formatter = formatter;
}
public void move(int x,int y){
formatter.format("%s The Turtle is at (%d,%d)\n",name,x,y);
}
public static void main(String[] args) {
PrintStream printStream = System.out;
Turtle tommy = new Turtle("tommy", new Formatter(System.out));
Turtle terry = new Turtle("terry", new Formatter(printStream));
tommy.move(12, 13);
terry.move(41, 29);
}
}
Formatter的构造函数经过重载可以接受多种输出目的,但常用的还是PrintStream()
格式化修饰符 “%s”
public class Receipt {
private double total = 0;
private Formatter formatter = new Formatter(System.out);
public void printTitle(){
formatter.format("%-15s %5s %10s\n", "Item", "Qty", "Price");
formatter.format("%-15s %5s %10s\n", "---", "---", "---");
}
public void print(String name, int qty, double price) {
formatter.format("%-15.15s %19d %10.2f\n", name, qty, price);
total += price;
}
public void printTotle(){
formatter.format("%-15.15s %5s %10.2f\n", "Tax", "", total * 0.06);
formatter.format("%-15s %5s %10s\n", "", "", "-----");
formatter.format("%-15.15s %5s %10.2f\n", "Total", "", total * 1.06);
}
public static void main(String[] args) {
Receipt receipt = new Receipt();
receipt.printTitle();
receipt.print("一号", 15, 6.37);
receipt.print("二号", 17, 5.51);
receipt.printTotle();
}
}
“%d” 整数十进制
“%f” 浮点十进制
“%s” String
Formaater默认情况下是右对齐,可以通过”-“改变对齐方向
正则表达式
matches方法可以判断当前的字符串是否匹配给定的正则表达式。如果匹配,返回true,否则,返回false。
split方法使用正则表达式来分割字符串,并以String数组的形式返回分割结果
replaceAll 和 replaceFirst方法
这两个方法用replacement替换当前字符串中和regex匹配的字符串。
一、校验数字的表达式
数字:^[0-9]*$
n位的数字:^\d{n}$
至少n位的数字:^\d{n,}$
m-n位的数字:^\d{m,n}$
零和非零开头的数字:^(0|[1-9][0-9]*)$
非零开头的最多带两位小数的数字:^([1-9][0-9]*)+(.[0-9]{1,2})?$
带1-2位小数的正数或负数:^(\-)?\d+(\.\d{1,2})?$
正数、负数、和小数:^(\-|\+)?\d+(\.\d+)?$
有两位小数的正实数:^[0-9]+(.[0-9]{2})?$
有1~3位小数的正实数:^[0-9]+(.[0-9]{1,3})?$
非零的正整数:^[1-9]\d*$ 或 ^([1-9][0-9]*){1,3}$ 或 ^\+?[1-9][0-9]*$
非零的负整数:^\-[1-9][]0-9″*$ 或 ^-[1-9]\d*$
非负整数:^\d+$ 或 ^[1-9]\d*|0$
非正整数:^-[1-9]\d*|0$ 或 ^((-\d+)|(0+))$
非负浮点数:^\d+(\.\d+)?$ 或 ^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$
非正浮点数:^((-\d+(\.\d+)?)|(0+(\.0+)?))$ 或 ^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$
正浮点数:^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$ 或 ^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$
负浮点数:^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$ 或 ^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$
浮点数:^(-?\d+)(\.\d+)?$ 或 ^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$
二、校验字符的表达式
汉字:^[\u4e00-\u9fa5]{0,}$
英文和数字:^[A-Za-z0-9]+$ 或 ^[A-Za-z0-9]{4,40}$
长度为3-20的所有字符:^.{3,20}$
由26个英文字母组成的字符串:^[A-Za-z]+$
由26个大写英文字母组成的字符串:^[A-Z]+$
由26个小写英文字母组成的字符串:^[a-z]+$
由数字和26个英文字母组成的字符串:^[A-Za-z0-9]+$
由数字、26个英文字母或者下划线组成的字符串:^\w+$ 或 ^\w{3,20}$
中文、英文、数字包括下划线:^[\u4E00-\u9FA5A-Za-z0-9_]+$
中文、英文、数字但不包括下划线等符号:^[\u4E00-\u9FA5A-Za-z0-9]+$ 或 ^[\u4E00-\u9FA5A-Za-z0-9]{2,20}$
可以输入含有^%&’,;=?$\”等字符:[^%&',;=?$\x22]+
禁止输入含有~的字符:[^~\x22]+