不可变String
String
对象是不可变的,String
类中每一个看起来会修改String
值的方法,实际上都是创建了一个全新的String
对象,以包含修改后的字符串内容,而最初的String
对象则丝毫未动。
1 | public class Immutable { |
重载 “+” 与StringBuilder
String
对象是不可变的,不可变性会带来一定的效率问题。为String
对象重载的“+”操作符就是一个例子。(用于 “+” 与 “+=” 是Java中仅有的两个重载过的操作符,而Java并不允许程序员重载任何操作符)。
虽然编译器已经自动优化,用StringBuilder
实现字符串拼接操作来避免生成多余对象,但是还是建议对于复杂的字符串拼接,在代码中主动使用StringBuilder
,因为这样效率最高。
无意识的递归
Java中的每个类从根本上都是继承自Object
,标准容器类自然也不例外。因此容器类都有toString()
方法,并且覆写了该方法,使得它生成的String
结果能够表达容器自身,以及容器所包含的对象。例如ArrayList.toString()
,它会遍历ArrayList
中包含的的所有对象,调用每个元素上的toString()
方法。
如果你希望toString()
方法打印出对象的内存地址,也许你会考虑使用this
关键词:
1 | public class InfiniteRecursion { |
当你创建了InfiniteRecursion
对象,并将其打印的时候,你会得到一串非常长的异常。如果你将该InfiniteRecursion
对象存入一个ArrayList
中,然后打印该ArrayList
,你也会得到同样的异常。编译器尝试将this
转换成一个String
是通过调用this
上的toString()
方法,于是就发生了递归调用。
如果你真的想要打印出对象的内存地址,应该调用Object.toString()
方法,这才是负责任的方法。所以,你不该使用this
,而是应该调用super.toString()
方法。
正则表达式
正则表达式是一种强大而灵活的文本处理工具。
量词
量词描述了一个模式吸收输入文本的方式:
- 贪婪型(默认):它的特性是一次性地读入整个字符串,如果不匹配就吐掉最右边的一个字符再匹配,直到找到匹配的字符串或字符串的长度为0为止。它的宗旨是读尽可能多的字符,所以当读到第一个匹配时就立刻返回。
- 勉强型(在匹配次数的特殊字符后面加一个问号):它的特性是从字符串的左边开始,试图不读入字符串中的字符进行匹配,失败,则多读一个字符,再匹配,如此循环,当找到一个匹配时会返回该匹配的字符串,然后再次进行匹配直到字符串结束。
- 占有型:它和贪婪模式很相似,不同点是不匹配它不会往回吐字符再匹配。
1 | public class RegexMatches |