字符串是计算机程序最常见的行为,毋庸置疑
String对象是不可变的,String类中看起来会修改String值的方法,每一个都创建了一个全新的对象
// 这是一段简易代码 String q = "哈哈哈"; // 将q传递给方法时,传递的是引用的拷贝,复制了一份新的引用,并不是q所指的对象 // 只有当upcase()方法运行的时候,这个引用才存在,s.toUpperCase()返回的又是一个新的对象 public String upcase(String s) { return s.toUpperCase(); } // 也就是说,这一系列操作下来,有三个对象:q、参数s、qq String qq = upcase(q); 这就和传递对象的方法有很大区别了,我们都知道,传递对象的话,会修改对应对象的内容任何指向String的引用都不可能改变它的值
我们常会听说不要使用 “+”来连接字符串,但是其中的原因是什么呢
对于 “+” 操作,编译器会自作主张的使用StringBuilder对象来优化我们的代码,因为StringBuilder更高效 书中的例子是这样的: 1、for循环去 += String对象 每一次循环都会去创建一个新的StringBuilder对象 2、创建一个StringBuilder对象,for循环去append 只生成了一个StringBuilder对象,并且还可以提前指定大小 那么对于简单的字符串操作,可以考虑使用 “+” 但是对于复杂的一些字符串操作,比如在toString()方法中使用循环,那么一定要考虑使用StringBuilderStringBuilder是Java SE5引入的,在这之前是StringBuffer,线程安全的,开销大一些。Java5之后字符串的操作会更快一点
练习1、简单的字符串操作生成很少的StringBuilder,比如只生成一个StringBuilder,代码还是比较合理的
容器的toString()方法会遍历容器中的所有对象,调用每个元素上的toString()方法
如果想打印对象的内存地址,不要使用this
比如toString()中有如下代码: return "address" + this 编译器试着把this转换成一个String对象,怎么转换呢,只能调用本身的toString()方法,那么就是递归调用了 真想打印对象地址,应该使用Object.toString()方法,super.toString()方法练习2、略
这个操作就不多说了,大部分挺熟悉了,都是常用的,搞个图吧:
比如在项目中进行一些字符串的操作,或者说在一些编程的算法题中常用的有:
length(),chatAt(),toCharArray(),contains(),indexof(),substring(),replace(),trim(),valueOf()
13.5.1 printf()
// 这行代码运行的时候,将x插入到%d的位置,将y插入到%f的位置 // 并且表示x是一个整数,y是一个浮点数 printf("[%d %f]\n", x, y);13.5.2 System.out.format()
format()和printf()是等价的,都是格式化输出,和System.out.println()是不一样的
13.5.3 Formatter类
格式化输出一些东西,其实主要的应用还是数字、日期、金额、类似超市购物单的小票等
构造器经过重载可以接受多种输出目的地,比如PrintStream()、OutputStream()和File
练习3、略
13.5.4 格式化说明符
要想控制空格和对齐,需要更加精细复杂的格式修饰符
width:一个域的最小尺寸
precision:最大尺寸
应用于String,代表输出字符的最大数量,应用于浮点数,表示要显示出来的小数位数,位数过多舍入,太少会在尾部补零应用于整数,会触发异常练习4、略
13.5.5 Formatter转换
有要特殊注意的地方,将一个变量转换为boolean型或者Boolean对象,只要该参数不为null,即使是0,转换的结果依然还是true
练习5、略
13.5.6 String.format()
这是一个静态方法,接受和Formatter.format()一样的参数,最终返回一个String对象
在String.format()内部也是创建一个Formatter对象,使用便捷的String.format()方法更好些
练习6、略
13.6.1 基础
// 理解下面的代码:以-或+开头或二者皆没有,后面跟着一位或者多位数字 (-|\\+)?\\d+String还自带了一个非常有用的正则表达式工具——split()方法,将字符串从正则表达式匹配的地方切开
练习7、略
练习8、略
练习9、略
13.6.2 创建正则表达式
参考java.util.regex中的Pattern类,这里就不说了
13.6.3 量词
简单的比如说: X? X?? X?+ 一个或零个X X* X** X?* 零个或多个X X+ X+? X++ 一个或多个X接口CharSequence从CharBuffer、String、StringBuffer、StringBuilder类中抽象出了一些定义,多数正则表达式操作都接受CharSequence类型的参数
13.6.4 Pattern和Matcher
导入java.util.regex包,用Pattern.cimpile方法编译正则表达式,然后会生成一个Pattern对象,将要检索字符串传入matcher()方法,matcher()方法会生成一个Matcher()对象,它有很多功能可用
练习10、略
练习11、略
组(Groups)
组是用括号划分的正则表达式
A(B(C))D 组0是ABCD 组1是BC 组2是C练习12、略
start()与end()
这个略了
练习13、略
Pattern标记
13.6.5 split()
略
练习14、略
13.6.6 替换操作
replaceFirst(),replaceAll()等
13.6.7 reset()
略
13.6.8 正则表达式与Java I/O
略
练习15、略
练习16、略
练习17、略
练习18、略
练习19、略
Java SE5新增了Scanner类,大大减轻扫描输入的工作负担
练习20、略
13.7.1 Scanner定界符
略
13.7.2 用正则表达式扫描
略
StringTokenizer已经可以废弃了
到目前为止,Java对字符串的操作的支持已经很完善了,不过要注意细节上的问题,比如恰当的使用StringBuilder等
正则表达式后面很多内容都略了,大体了解一下,感觉先把基本的String理解了,基本操作掌握了,格式化输出在需要的时候也要掌握。等有时间就回过头来再看看