Java编程思想--13字符串

Oriole ·
更新时间:2024-09-20
· 564 次阅读

第十三章 字符串13.1 不可变的String13.2 重载“+”与StringBuilder13.2.1 javap反编译13.3 无意识的递归13.4 String常用方法13.5格式化输出13.5.1 printf()13.5.2 System,out.format()13.5.3 Formatter类13.5.4 格式化说明符13.5.5 Formatter转换13.5.6 String.format()13.6正则表达式13.6.1 基础13.6.2 创建正则表达式(1)字符(2)字符类13.6.3 量词13.6.4 Pattern与Matcher13.6.5 split()13.6.6 替换操作13.6.7 reset()13.7 扫描输入13.8 StringTokenizer 13.1 不可变的String

String对象是不可变的,每一次修改实际上都是创建了一个新的String对象。

13.2 重载“+”与StringBuilder

String的“+”与“+=”用于拼接字符串,但由于String是可变的,拼接多个字符串时会造成大量的垃圾。Java对此进行了优化,当拼接多个字符串时,编译器自动引用了StringBuilder变量。(新版本与书上例子不同)
使用StringBuilder可以很高效的进行字符串拼接。并且包含了丰富的方法:insert()、replace()、subString()、reverse()。其中append()与toString()比较常用。

public class Concatenation { public static void main(String[] args) { String mango = "mango"; String s = "abs" + mango + "def" + 47; System.out.println(s); } } public class chapter13.Concatenation { public chapter13.Concatenation(); Code: 0: aload_0 1: invokespecial #1 // Method java/lang/Object."":()V 4: return public static void main(java.lang.String[]); Code: 0: ldc #7 // String mango 2: astore_1 3: aload_1 4: invokedynamic #9, 0 // InvokeDynamic #0:makeConcatWithConstants:(Ljava/lang/String;)Ljava/lang/String; 9: astore_2 10: getstatic #13 // Field java/lang/System.out:Ljava/io/PrintStream; 13: aload_2 14: invokevirtual #19 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 17: return } 13.2.1 javap反编译

对当前class字节码进行反编译生成汇编代码

javac chapter13\Concatenation.java javap -c chapter13\Concatenation 13.3 无意识的递归

下面的程序,在覆盖的方法toString中,字符换拼接碰到了对象引用,会自动调用this对象的toString()方法,于是发生了递归调用。
为了消除递归,应该调用super.toString。

import java.util.*; public class InfiniteRecursion { public String toString() { return " InfiniteRecursion address: " + this + "\n"; } public static void main(String[] args) { List v = new ArrayList(); for(int i = 0; i < 10; i++) v.add(new InfiniteRecursion()); System.out.println(v); } } ///:~ 13.4 String常用方法
方法 参数返回值 描述
length() - 返回字符串长度
charAt() int索引 返回该索引上的char
toCharArray() - 生成char[], 里面包含String所有字符
equals(), equalsIgnoreCase() 与之相比的String 比较两个字符串内容是否相同 (忽略大小写)
compareTo, compareToIgnoreCase() 与之相比的String 按字典序比较两个字符串的内容
contains() 要搜索的CharSequence() 如果包含参数的内容,则返回True
contentEquals() 与之进行比较的CharSequence或者StringBuffer 如果包含参数的内容,则返回True
regionMatcher() 当前String索引的偏移量与另一个String索引的偏移量,要求比较的长度 boolean
startsWith 可能起始的String,重载增添了offset boolean
endsWith boolean endssWith​(String prefix) boolean
indexOf(), lastIndexOf char或char的索引 返回目标索引,如果不存在则返回-1
subString() 起始索引,起始+终止索引 返回新的String子串
concat() 要连接的String 返回已给您的String对象,包含两个字符串的拼接
replace() 要替换的字符串,用来替换的字符串 返回替换后的String对象,如果没有发生替换,则返回原始对象
toLowerCase(), toUpperCase() - 改变字符串大小写。若无需改变则返回原始String对象
trim() - 去掉两端空白字符,若无需改变则返回原始String对象
valueOf() 静态方法,重载版本为Object、boolean、char、int、long、short、float、double 返回
intern() - 详细解答
13.5格式化输出 13.5.1 printf() 13.5.2 System,out.format() 13.5.3 Formatter类

Formatter的构造器经过重载可以接受多种输出目的地。

13.5.4 格式化说明符

格式:%[argument_inde$][flags][width][.presion]conversion

“-”可以调整对齐方式,默认是右对齐。

import java.util.*; public class Receipt { private double total = 0; private Formatter f = new Formatter(System.out); public void printTitle(inr) { f.format("%-15s %5s %10s\n", "Item", "Qty", "Price"); f.format("%-15s %5s %10s\n", "----", "---", "-----"); } public void print(String name, int qty, double price) { f.format("%-15.15s %5d %10.2f\n", name, qty, price); total += price; } public void printTotal() { f.format("%-15s %5s %10.2f\n", "Tax", "", total*0.06); f.format("%-15s %5s %10s\n", "", "", "-----"); f.format("%-15s %5s %10.2f\n", "Total", "", total * 1.06); } public static void main(String[] args) { Receipt receipt = new Receipt(); receipt.printTitle(); receipt.print("Jack's Magic Beans", 4, 4.25); receipt.print("Princess Peas", 3, 5.1); receipt.print("Three Bears Porridge", 1, 14.29); receipt.printTotal(); } } /* Output: Item Qty Price ---- --- ----- Jack's Magic Be 4 4.25 Princess Peas 3 5.10 Three Bears Por 1 14.29 Tax 1.42 ----- Total 25.06 *///:~ 13.5.5 Formatter转换
类型转换符
d 整数型(十进制)
c Unicode字符
b Boolean值
s String
f 浮点数(十进制)
e 浮点数(科学计数)
x 整数(十六进制)
h 散列码(十六进制)
% 字符串%
13.5.6 String.format()

String.format()接受与Formatter.format()一样的参数,但是返回的是一个String对象。

13.6正则表达式 13.6.1 基础

\表示要插入一个正则表达式的反斜线其后面的字符有特殊的意义,例如,表示一位数字\d,表示\,应该使用\\。

“Hello”.matches(regular_string):检查字符串是否匹配某种模式 “Hello”.split(regular_string):根据正则表达式进行字符串分割,其重载版本限制了修改的次数。 13.6.2 创建正则表达式 (1)字符
字符 含义
B 指定字符B
\xhh 十六进制为xhh的字符
\uhhhh 十六进制为oxhhhh的Unicode字符
\t 制表符Tab
\n 换行符
\r 回车
\f 换页
\e 转义Escape
(2)字符类
字符类 含义
. 任意字符
[abc] 包含a,b,c的任何字符
[^abc] 除了a,b,c外的任何字符
[a-zA-Z] 从a到z或从A到Z的任何字符
abc[hij] 任意a,b,c,h,i,j字符(合并)
a-z&[hij] 任意h,i或j
\s 空白符(空格、tab、换行、换页、回车)
\S 非空白符[^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 前一个匹配的结束
13.6.3 量词 贪婪型:贪婪型表达式会为所有可能的模式发现尽可能多的匹配。 勉强型:用问号来指定,这个量词满足模式所需的最少的字符。 占有型:用+号来指定。此方式看可以防止回溯。
贪婪型 勉强型 占有型 含义
X? X?? X?+ 至多一个X
X* X*? X*+ 任意个X
X+ X+? X++ 至少一个X
X{n} X{n}? X{n}+ 恰好n次X
X{n,} X{n,}? X{n}+ 至少n次X
X{n,m} X{n,m}? X{n, m}+ X至少n次且不超过m次

表达式通常用圆括号包围起来,以便按照我们期望的效果去执行。

13.6.4 Pattern与Matcher

Pattern与Matcher组合是比String强大的正则表达式工具。

用法

先创建Pattern对象,位于java.util.regex包,然后调用Pattern.compile()方法来编译正则表达式,来产生Pattern对象。 调用Pattern.matcher()方法,该方法将会产生一个Matcher对象,该对象会有很多功能。 boolean matches() lookingAt():判断该字符串的始部分(不必是整个字符串)是否能够匹配模式。 find():进行查找,查找成功,会跳到下一个 find(int start):从第start个位置开始查找 start(), end():当前匹配项的起始位置 group():当前匹配的字符串 groupCount:返回匹配到的个数 import java.util.regex.*; // import static net.mindview.util.Print.*; public class Finding { public static void main(String[] args) { Matcher m = Pattern.compile("\\w+") .matcher("Evening is full of the linnet's wings"); while(m.find()) System.out.print(m.group() + " "); System.out.println(); int i = 0; while(m.find(i)) { System.out.print(m.group() + " "); i++; } } } /* Output: Evening is full of the linnet s wings Evening vening ening ning ing ng g is is s full full ull ll l of of f the the he e linnet linnet innet nnet net et t s s wings wings ings ngs gs s *///:~ 13.6.5 split()

split()方法可以很便捷的将输入字符串断开形成对象数组。

13.6.6 替换操作 replaceFirst(String replacement):替换第一个 replaceAll(String replacement):替换所有 appendReplacement(String sbuf, String replacement):允许渐进式替换。 13.6.7 reset()

通过reset()方法,可以将现有的Matcher对象应用到新的字符序列。如果使用不带参的reset(),可以将Matcher对象重新设置到当前字符序列的起始位置。

13.7 扫描输入 13.8 StringTokenizer

可以用更加强大的split和正则表达式代替。

nianmaodu 原创文章 16获赞 1访问量 522 关注 私信 展开阅读全文
作者:nianmaodu



JAVA java编程思想 java编程 字符串 字符

需要 登录 后方可回复, 如果你还没有账号请 注册新账号