字符串
不可变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()
就能获得匹配结果。如果正则表达式中有定界符,将永远不会匹配成功。