字符串
不可变String
String对象是不可变的。String类中每一个看起来会修改String值的方法,实际上都是创建了一个全新的String对象。- 对于一个方法而言,参数是为该方法提供信息的,而不是想让该方法改变自己。
重载“+”与StringBuilder
- 重载:一个操作符在应用于特定的类时,赋予其特定的含义。
- 在Java中,用于
String的+和+=是仅有的两个重载过的操作符,不允许程序员重载任何操作符。 - Java编译器会自动优化
String操作并使用StringBuilder,因为其高效,但是并不是所有的状况都会被优化。因此在需要大量操作String时使用StringBuilder是明智的选择。
无意识递归
- 如果在
toString()方法中使用this指针与其它字符串拼接,试图打印对象的地址,那么会引起无限的递归调用。[因为编译器试图把this指针转换为String类型,而转换的方法就是调用this.toString()。正确的做法是调用父类的toString(),即super.toString()。
格式化输出
System.out.format()
- 类似于C语言中的
printf(),接受一个简单的格式化字符串以及一串参数。
Formatter类
- 创建
Formatter对象时需要向构造器中传入输出目标,例如System.out。使用时调用Formatter对象的format()方法。
格式化说明符
- 抽象语法:
%[argument_index$][flags][width][.precision]conversion width:控制一个域的最小尺寸,在有必要时添加空格,来确保一个域至少达到某个长度。可以用于各种类型的数据转换。默认情况下数据是右对齐,可以使用-来改变对齐方向。precision:指明数据的最大尺寸。不能用于所有的数据类型转换,例如整数类型,并且应用于不同的数据类型转换时意义也不同。应用于String时表示打印String时输出的字符的最大数量;应用于浮点数时,表示小数部分要显示的位数(默认是6位),多则舍入,少则补0。
Formatter转换
- 常用的类型转换:
| 类型转换字符 | 含义 |
|---|---|
| d | 整数型(十进制) |
| c | Unicode字符 |
| b | Boolean值 |
| s | String |
| f | 浮点数(十进制) |
| e | 浮点数(科学计数) |
| x | 整数(十六进制) |
| h | 散列码(十六进制) |
| % | 字符”%” |
- 关于b转换,对于
boolean基本类型和Boolean对象,其转换结果就是true或false;对于其它类型的参数,只要其不为null,那么转换结果就是true,即使是数字0,转换结果依然是true。
正则表达式
基本构造
| 字符 | 含义 |
|---|---|
| B | 指定字符B |
| \xhh | 十六进制值为0xhh的字符 |
| \uhhhh | 十六进制表示为0xhhhh的Unicode字符 |
| \t | 制表符Tab |
| \n | 换行符 |
| \r | 回车 |
| \f | 换页 |
| \e | 转义(Escape) |
| 字符类 | 含义 |
|---|---|
| . | 任意字符 |
| [abc] | 包含a、b、c的任何字符,同 a|b|c |
| [^abc] | 除了a、b、c的任何字符(否定) |
| [a-zA-Z] | 从a到z或从A到Z的任何字符 |
| \s | 空白符(空格、Tab、换行、换页和回车) |
| \S | 非空白符 |
| \d | 数字,同[0-9] |
| \D | 非数字,[^0-9] |
| \w | 词字符,[a-zA-Z0-9] |
| \W | 非词字符,[^\w] |
| 逻辑操作符 | 含义 |
|---|---|
| XY | Y跟在X后面 |
| X|Y | X或Y |
| (X) | 捕获组,可以在表达式中使用\i来引用第i个捕获 |
| 边界匹配符 | 含义 |
|---|---|
| ^ | 一行的开始 |
| $ | 一行的结束 |
| \b | 词的边界 |
| \B | 非词的边界 |
| \G | 前一个匹配的结束 |
量词
- 量词描述了一个模式吸收输入文本的方式
- 贪婪型:一次性地读入整个字符串,如果无法完成匹配就去掉最右边的一个字符再匹配,直到找到匹配的字符串或字符串的长度为0为止。它的宗旨是读尽可能多的字符,所以当读到第一个匹配时就立刻返回。
- 厌恶型:立刻进入匹配,如果无法匹配则多读一个字符串,直到匹配成功或者字符串读完。它尽量减少了匹配到的字符串,但同样读到第一个匹配的就返回。
- 占有型:仅匹配一次,失败不会再次尝试。
Pattern和Matcher
正则表达式对象:位于
java.util.regex包中,使用Pattern.compile()编译正则表达式,并返回一个Pattern对象。使用Pattern对象的matcher()方法检索一个字符串,会得到一个Matcher对象。Pattern对象的split()方法可以从匹配了正则表达式的地方分割输入的字符串,返回分割后的子字符串String数组。Matcher对象的find()方法可用来在CharSequence中查找多个匹配组:是用括号划分的正则表达式,可以根据组的编号来引用某个组。组号为0便是整个正则表达式,组号1表示第一对括号括起来的组。
Matcher对象中有许多关于组的方法:
| 方法名 | 用途 |
|---|---|
int groupCount() |
返回Matcher对象中组数,不包含第0组 |
String group() |
返回前一次匹配的第0组 |
String group(int i) |
返回前一次匹配的指定组号,如果匹配成功但是指定的组没有匹配输入字符串的任何部分则返回null |
int start(int group) |
返回前一次匹配操作中寻找到的组的起始索引 |
int end(int group) |
返回前一次匹配操作中寻找到的组的最后一个字符索引加1的值 |
替换
| 方法名 | 用途 |
|---|---|
String replaceFirst(String replacement) |
用replacement替换掉第一个匹配成功的部分 |
String replaceAll(String replacement) |
用replacement替换所有匹配成功的部分 |
Matcher appendReplacement(StringBuffer sb, String replacement) |
1. 先将不匹配的地方放入sb中,即从上次读取的位置开始,到本次start() - 1;2. 将replacement放入sb中;3. 将读取位置改为end() |
StringBuffer appendTail(StringBuffer sb) |
在多次使用appendReplacement()方法后,使用此方法将把剩余部分的字符串直接放入sb中 |
reset()
reset()可以将现有的Matcher对象应用于一个新的字符序列。
扫描输入
Scanner定界符
- 默认情况下,
Scanner对象使用空白字符对输入进行分词。使用Scanner对象的useDelimiter()并输入正则表达式作为参数可以修改成自定义的定界符。
用正则表达式扫描
Scanner对象的hasNext()和next()方法都支持输入一个Pattern对象,找到下一个匹配该模式的部分,调用match()就能获得匹配结果。如果正则表达式中有定界符,将永远不会匹配成功。
