《Java编程思想》笔记 第十三章 字符串
1.String对象不可变
- String对象不可变,只读。任何指向它的引用都不能改变它的内容。改变String内容意味着创建了一个新的String对象。
- String 对象作为方法参数时都会复制一份引用(不是复制对象),而引用指向的对象一直呆在单一物理位置上。
2.重载操作符和StringBuild
- + += 这2个符号作用于字符串和基本类型数据时意义不相同,Java只有这2个操作符被重载过。
2.1 拼接字符串 + += 编译器会调用StringBuild来工作。
2.2 拼接字符串时编译器会创建一个StringBuild对象来生成最终的String,并且调用append方法来拼接字符串,最后用toString输出。(一条表达式生成一个StringBuild对象)
2.3 如果 + +=在循环内,就会生成多个StringBuild对象,影响性能。如果在循环外创建StringBuild对象循环内调用append方法,就会只有一个对象。
7.Object的toString方法输出对象引用地址,所有类都继承它,但大多数类覆写了toString方法,用来输出对象内容的字符串。
3.无意识的递归
- 打印对象引用会调用toString,this代表调用当前方法的引用,所以this在toString中会发生递归调用。
4.格式化输出
4.1输出流的两种格式化输出方法。
- printf( ) 这和C语言中的一样,使用%d、%f、%s等占位符,但C语言中不能拼接字符串,Java可以。
- format()和printf( )一样,printf()调用了format()方法
4.2 Formatter类
4.2.1 新的格式化输出功能都由Formatter类提供。
4.2.2 创建Formatter对象要给构造器传递一些信息,告诉它最后输出到哪。
4.2.3 格式化说明符
- %[argument_index$] [flags] [width] [.precision] conversion [ ] 内为可略内容
1. argument_index 是一个十进制整数, 2$表示使用参数列表的第2个参数 。
2. flags 是修改输出格式的字符集。有效标志的集合取决于转换类型。
3. width 是一个非负十进制整数,至少达到多少长度,不够用空格补齐,默认右对齐。
4. precision 是一个非负十进制整数,前面有个点,和width区分。通常用来限制字符数,表示最多多少位。
整数无法使用,String型输出最大字符量,浮点型表示小数点位数,不足补0,超过四舍五入。
5. 浮点数 %f 默认输出小数点后6位
6. %b 对于Boolean 和 boolean型可以准确输出,对于其他类型只要不是null,就为true,0也是true。
4.2.4 静态方法 String.format()返回一个String, 如果只使用一次format()方法,这个比较简单。
5.正则表达式
5.1 String自带的正则表达式工具
- s.split(regex) 将字符串从正则表达式匹配的地方割开,并返回String数组。
- s.matches(regex) 返回boolean值, 是否能匹配到正则。
- s.replaceFirst(regex a)将第一个匹配到的正则换为a. s.replaceAll(regex a)替换全部。
- 只使用一次正则表达式建议使用自带的
5.2 创建正则表达式对象
5.2.1 创建一个正则表达式对象 Pattern p = Pattern.compile(regex);
Pattern 是 final 类 只能通过静态方法它的compile创建对象。
5.2.2 Matcher m = p.matcher(string);
Matcher 同样也是 final 类
Pattern对象的matcher方法接受一个字符串并生成一个 Matcher 匹配器对象 ,通过匹配器可以获得字符串与正则的关系
5.2.3 匹配器的一些方法:
- m.matches() 整个字符串是否匹配正则
- m.lookingAt() 字符串的起始部分是否匹配
- m.find() 查找下一个匹配(下一个意味着有迭代行为)
- m.find(int start) 从指定位置开始匹配
- find 只负责匹配,不返回匹配到的结果,匹配到的结果由group()获取。
5.3 组
- 组是用括号划分的正则表达式,由外向内,由左向右 编号0 1 2 3 。。。叫 组0,组1,组2 。。。
5.3.1 Matcher对象获得组相关信息的方法
- public int groupCount() 返回组的数量,不包括组0
- public String group() 返回前一次的全匹配(组0)相当于group(0)
- public String group(int i ) 返回 前一次匹配期间指定组,若之前匹配成功,指定组未能匹配则返回null
- start(int group) 返回匹配到的指定组的起始位置索引。
- start()返回匹配到的正则起始索引。
- end(int group) 返回匹配到的指定组的最后一位索引再加一。
- end()返回匹配到的正则最后一位索引再加一。
6 Pattern标记
- Pattern.compile(regex,int flage) flage来自pattern类中的常量,可以调整匹配行为,是对正则式的一种约定。可是使用 | 组合多个标记。
- Pattern.CANON_EQ 两个字符当且仅当它们的完全规范分解相匹配时,就认为它们是匹配的。
- Pattern.CASE_INSENSITIVE(?i) 默认情况下,大小写不敏感的匹配假定只有US-ASCII字符集中的字符才能进行。这个标记允许模式匹配不必考虑大小写(大写或小写)。通过指定UNICODE_CASE标记及结合此标记。基于Unicode的大小写不满干的匹配就可以开启了。
- Pattern.COMMENTS(?x) 在这种模式下,空格符将被忽略掉,并且以#开始直到行末的注释也会被忽略掉。
- Pattern.DOTALL(?s) 在dotall模式中,表达式"." 匹配所有字符,包括终结符。默认情况下,”." 表达式不匹配行终结符。
- Pattern.MULTILINE(?m) 在多行模式下,表达式^和$分别匹配一行的开始和结束。^还匹配输入字符串的开始,而$还匹配输入字符串的结尾。默认情况下,这些表达式仅匹配输入的完整字符串的开始和结束。
- Pattern.UNICODE_CASE(?u) 当指定这个标记, 并且开启CASE_INSENSITIVE时,大小写不敏感的匹配将按照与Unicode标准相一致的方式进行。默认情况下,大小写不敏感的匹配假定只能在US-ASCII 字符集中的字符才能进行
- Pattern.UNIX_LINES(?d) 在这种模式下,在., ^和$行为中, 只识别行终结符\n
7 split()
- 切割字符串并返回切割后的字符串数组,一切split()方法底层都由Pattern的split()方法提供支持。
1.Pattern.compile(regex).split(String string);
2.Pattern.compile(regex).split(String string, int limit); 从第limit个开始不分割,包括limit。
8 替换
1.String自带替换
- public String replaceFirst(String regex,String replacement) 只替换第一个匹配到的正则。
- public String replaceAll(String regex,String replacement) 替换全部。
2. Matcher 替换
- Pattern.compile(regex).matcher(str).replaceFirst(repl) // String 方法的底层实现。
- Pattern.compile(regex).matcher(str).replaceAll(repl) // String 方法的底层实现。
- appendReplacement(StringBuffer sb, String replacement) 渐进式替换
Pattern p = Pattern.compile("cat"); Matcher m = p.matcher("one cat two cats in the yard"); StringBuffer sb = new StringBuffer(); //用于接收被替换的部分 while (m.find()) { m.appendReplacement(sb, "dog"); //System.out.println(sb.toString()); } m.appendTail(sb); //把剩余部分存入sb System.out.println(sb.toString());
//one dog
//one dog two dog
//one dog two dogs in the yard
3 reset()
- m. reset(string) 将Matcher对象应用与一个新的字符串,中途改变要匹配的字符串。
9 正则与IO
10 扫描输入 Scanner
- 对输入进行分词
1.scanner构造器接受任何类型的输入对象。
2.普通next()方法返回下一个string对象。
3.基本类型除char外的 nextXXX() 方法都返回对应类型的数字。
4.next方法只有找到一个完整的分词后才返回,否则线程挂起等待。
5.hasNexXXX()方法判断下一个分词是否是需要的类型。
6.scanner默认对空字符串分割。
7.scanner.useDlimiter(regex) 使用正则对输入分词
8.scanner.dlimiter() 返回 当前正则匹配到的字符串,并作为Pattern对象。
9 正在扫描
- nextXXX( string)和hasNex(string)都可以传入String进行匹配。(注意是匹配不是分词)。也可以传入string类型和pattern类型的正则进行匹配。
- 用正则匹配后调用scanner.match(),返回MatcherResult类型的扫描匹配结果。它包含了获得的内容及捕获组位置,通过group(i)获得对应组信息。
下一篇: 曾国荃是什么人?他跟曾国潘是什么关系?