1、不可变String
String对象是不可变的。
2、重载“+”与StringBuilder
String对象是不可变的,可以给一个String对象加任意的别名。因为String对象具有只读特性,所以指向它的任何引用都不可能改变它的值。
String对象的不可变性带来一定的效率问题。为String对象重载的“+”操作符就是一个例子。
StringBuilder提供了丰富的方法,包括insert()、replace()、substring()甚至reverse(),最常用的还是append()和toString(),还有delete()方法。StringBuilder比StringBuffer(线程安全)效率更高。
3、无意识的递归
public String toString() {
return " InfiniteRecursion address: " + this + "\n";
}
这里发生了自动类型转换,由类类型转换为String类型。这里通过调用this上的toString()方法,于是就发生了递归调用。
4、String上的操作
当需要改变字符串内容时,String类的方法都会返回一个新的String对象。如果内容没有发生改变,String的方法只是返回指向原对象的引用而已。这可以节约存储空间以及避免额外的开销。
5、格式化输出
System.out.format():需要一个简单的格式化字符串,加上一串参数。例如,System.out.format("Row 1:[%d %f]\n",x,y)。
Formatter类:Formatter的构造器经过重载可以接受多种输出目的地,不过常用的还是PrintStream、OutputStream和File。
格式化说明符:%[argument_index$][flags][width][.precision]conversion (常规类型、字符类型和数值类型的格式说明符的语法)
可选的 argument_index 是一个十进制整数,用于表明参数在参数列表中的位置。第一个参数由 "1$" 引用,第二 个参数由 "2$" 引用,依此类推。
可选 flags 是修改输出格式的字符集。有效标志集取决于转换类型。
可选 width 是一个非负十进制整数,表明要向输出中写入的最少字符数。
可选 precision 是一个非负十进制整数,通常用来限制字符数。特定行为取决于转换类型。(应用于String时,String输出的最大数量;应用于浮点数时,小数位显示的位数,多则舍,少则尾部补零;无法应用于整数)
所需 conversion 是一个表明应该如何格式化参数的字符。给定参数的有效转换集取决于参数的数据类型。
String.format()
6、正则表达式
应用正则表达式的最简单的途径,就是利用String类内建的功能:
matches():检查一个String是否匹配正则表达式。
split():将字符串从正则表达式匹配的地方切开。
replaceFirst():替换正则表达式第一个匹配的子串。
replaceAll():替换所有匹配的地方。
创建正则表达式
量词:
正则中的数量词有Greedy (贪婪)、Reluctant(懒惰)和Possessive(强占)三种
Greedy是最常用的,它的匹配方式是先把整个字符串吞下,然后匹配整个字符串,如果不匹配,就从右端吐出一个字符,再进行匹配,直到找到匹配或把整个字符串吐完为止。
Reluctant正好和Greedy相反,它先从最小匹配开始,先从左端吞入一个字符,然后进行匹配,若不匹配就再吞入一个字符,直到找到匹配或将整个字符串吞入为止。
Possessive和Greedy的匹配方式一样,先把整个字符串吞下,然后匹配整个字符串,如果匹配,就认为匹配,如果不匹配,就认为整个字符串不匹配,它不会从右端吐出一个字符串再进行匹配,只进行一次。
接口CharSequence从CharBuffer、String、StringBuffer、StringBuilder类之中抽象出了字符序列的一般化定义。这些类都实现了该接口,多数正则表达式操作都接受CharSequence类型的参数。
Pattern和Matcher
Pattern p = Pattern.compile(正则表达式);
Matcher m = p.matcher(字符串);
Matcher上的方法:
boolean matches() :判断整个输入字符串是否匹配正则表达式。
boolean lookingAt():判断该字符串的开始部分是否能够匹配正则表达式。
boolean find(): 向前遍历字符串查找多个匹配。
boolean find(int start) :从参数位置开始遍历。
组
组是用括号划分的正则表达式,可以根据组的编号来引用某个组。组号0表示整个表达式,组号1表示被第一对括号括号括起来的组,依此类推。例如,A(B(C))D中有三个组:组0是ABCD,组1是BC,组2是C。
Matcher对象提供了一系列方法,用以获取与组相关的信息:
int groupCount():返回该匹配器的模式中的分组数目,第0组不包括在内。
String group():返回前一次匹配操作(例如find())的第0组(整个匹配)。
String group(int i):返回在前一次匹配操作期间指定的组号。
int start(int group):返回在前一次匹配操作中寻找到的组的起始索引。
int end(int group):返回在前一次匹配操作中寻找到的组的最后一个字符索引加一的值。
Pattern标记
Pattern类的compile()方法还有另一个版本,它接受一个标记参数,以调整匹配行为:
Pattern Pattern.compile(String regex, int flag);
其中flag来自以下Pattern类中的常量:
Pattern.CASE INSENSITIVE (?i):这个标记允许模式匹配不必考虑大小写。
Pattern.DOTALL (?s) :“.”匹配所有字符,包括行终结符。
Pattern.COMMENTS (?x):空格符将被忽略掉,并且以#开始直到行末的注释也会被忽略掉。
Pattern.MULTILINE (?m):^匹配输入字符串的开始;$匹配输入字符串的结尾。
Pattern类中split()方法
String[] split(CharSequence input) :将输入字符串断开成字符串对象数组,断开边界由正则表达式
String[] split(CharSequence input, int limit):第二个参数限制将输入分割成字符串数组的大小。
Matcher对象替换操作
replaceFirst(String replacement):以参数字符串替换掉第一个匹配成功的部分。
replaceAll(String replacement):以参数字符串替换所有匹配成功的部分。
appendReplacement(StringBuffer sbuf,String replacement):执行渐进式替换,允许你调用其他方法生成或处理replacement。
appendTail(StringBuffer sbuf):在执行一次或者多次appendReplacement()之后,调用此方法将输入字符串余下部分复制到sbuf中。
Matcher类中reset()方法
reset(String str):将现有的Matcher对象应用于一个新的字符序列。
reset():将Matcher对象重新设置到当前字符序列的起始位置。
7、扫描输入
Scanner类:Scanner构造器可以接受任何类型的输入对象,包括File对象、InputStream、String或者Readable对象。普通的next()方法返回下一个String。所有的基本类型(除char之外)都有对应的next()方法,包括BigDecimal和BigInteger。Scanner还有相应的hasNext方法,用以判断下一个输入分词是否所需的类型。
Scanner定界符:useDelimiter()来设置定界符。
用正则表达式扫面:
Scanner中next()方法配合指定正则表达式,找到下一个匹配该模式的输入部分,调用match()方法就可以获得匹配结果。
8、StringTokenizer
分割字符串:StringTokenizer可以废弃不用了,可以选择使用正则表达式和Scanne