java编程思想读书笔记 第十三章 字符串(上)
来源:互联网 发布:安卓乳摇软件 编辑:程序博客网 时间:2024/05/16 08:57
1.不可变字符串
String对象是不可变的。String类中每一个看起来会修改String值的方法,实际上是创建了一个全新的String对象,以包含修改后的字符串内容。而最初的String对象则丝毫未变。
看看下面的代码:
public class Immutable { public static String upcase(String s) { return s.toUpperCase(); } public static void main(String[] args) { String q = "howdy"; System.out.println(q); // howdy String qq = upcase(q); System.out.println(qq); // HOWDY System.out.println(q); // howdy q还是q }}
当q传给upcase()方法时,实际传递的是引用的一个拷贝。其实,每当把String对象作为方法的参数时,都会复制一份引用,而该引用所指的对象其实一直待在单一的物理位置上,从未动过。
2.重载“+”与StringBuilder
String对象是不可变的,你可以给一个String对象加任意多的别名。因为String对象具有只读特性,所以指向它的任何引用都不可能改变它的值,因此,也就不回对其他的引用有什么影响。
不可变性会带来一定的效率问题。为String对象重载的“+”操作符就是一个例子。重载的意思是,一个操作符应用于特定的类时,被赋予了特殊的意义(用于String的“+”与“+=”是java中仅有的两个重载过的操作符,而java并不允许程序员重载任何操作符)。操作符“+”可以用来连接String:
public class Test { public static void main(String[] args) { String mango ="mango"; String s = "abc" + mango + "def" + 47; System.out.println(s); }}
String有一个append()方法,它会生成一个新的String对象,以包含“abc”与mango连接好的字符串。然后该对象再与“def”相连,生成另一个新的String对象。
在使用”+”操作符时,编译器自动引入了java.lang.StringBuilder类,避免了连加情况下产生大量需要回收的垃圾(每+一次就会产生一个新的字符串)。因此,当为一个类编写toString()方法时,如果字符串操作简单,可以信赖编译器,它会为你合理的构造最终字符串结果。但是如果要在toString()中使用循环,那么最好自己创建一个StringBuilder对象,结合append()用它来构造最终结果。
例子如下:
public class UsingStringBuilder { public static Random random = new Random(47); public String toString(){ StringBuilder result = new StringBuilder("["); for (int i = 0; i < 25; i++) { result.append(random.nextInt(100)); result.append(","); } // 书上的result.length()-2是得不到它那个结果的,得到的结果是[58,55,93,61,61,29,68,0,22,7,88,28,51,89,9,78,98,61,20,58,16,40,11,22,] result.delete(result.length()-1, result.length()); result.append("]"); return result.toString(); } public static void main(String[] args) { UsingStringBuilder usb = new UsingStringBuilder(); System.out.println(usb); }}
输出:[58,55,93,61,61,29,68,0,22,7,88,28,51,89,9,78,98,61,20,58,16,40,11,22,4]
最终的结果是用append()语句一点点拼接起来的。如果你想走捷径,例如append(a+”:”+c),那编译器就会掉入陷阱,从而为你另外创建一个StringBuilder对象处理括号内的字符串操作。
StringBuilder提供了丰富而全面的方法,包括insert()、replace()、subString()甚至reverse(),但最常用的还是append()和toString(),delete()方法。StringBuilder是Java SE5引入的,在这之前还有Java的StringBuffer。StringBuffer是线程安全的,因此开销会大一些。StringBuilder字符串操作会更快一些。
3.无意识的递归
java中的每个类从基本上都是继承自Object,标准容器类自然也不例外。因此容器类都有toString()方法,并且覆写了该方法,使得它生成的String结果能够表达容器自身,以及容器所包含的对象。例如ArrayList.toString(),它会遍历ArrayList中包含的所有对象,调用每个元素上的
toString()方法。
如果希望toString()方法打印出对象的内存地址,不可以使用this关键字。如果这样写:
public class InfiniteRecursion { public String toString() { // return " InfiniteRecursion address: " + this + "\n"; return " InfiniteRecursion address: " + super.toString() + "\n"; } public static void main(String[] args) { List<InfiniteRecursion> v = new ArrayList<InfiniteRecursion>(); for (int i = 0; i < 3; i++) { v.add(new InfiniteRecursion()); System.out.println(v); } }}
输出为:
[ InfiniteRecursion address: com.test.InfiniteRecursion@6bbc4459
]
[ InfiniteRecursion address: com.test.InfiniteRecursion@6bbc4459
, InfiniteRecursion address: com.test.InfiniteRecursion@152b6651
]
[ InfiniteRecursion address: com.test.InfiniteRecursion@6bbc4459
, InfiniteRecursion address: com.test.InfiniteRecursion@152b6651
, InfiniteRecursion address: com.test.InfiniteRecursion@544a5ab2
]
编译器会试图将”+”后面的this转换为String,此时调用toString()函数,导致无穷递归。因此如果想要打印出内存地址,应该调用Object.toString()方法,所以调用super.toString()就可以了。
4.String上的操作
以下是String对象具备的一些基本方法。
从图中可以看出,当需要改变字符串的内容时,String类的方法都会返回一个新的String对象。同时,如果内容没有发生改变,String的方法只是返回指向原对象的引用而已。这可以节约存储空间以及避免额外的开销。
- java编程思想读书笔记 第十三章 字符串(上)
- java编程思想读书笔记----第十三章 字符串
- java编程思想读书笔记 第十三章 字符串(下)
- 《Java 编程思想》--第十三章:字符串
- JAVA编程思想-第十三章 字符串
- 《java编程思想》第十三章 字符串
- Java编程思想第四版读书笔记——第十三章 字符串
- java编程思想(第十三章)
- java编程思想读书笔记 第十章 内部类(上)
- java编程思想读书笔记 第十一章(上)
- java编程思想读书笔记 第十四章 类型信息(上)
- java编程思想读书笔记 第十五章 泛型(上)
- JAVA编程思想学习总结:第十三章字符串
- 《JAVA编程思想》学习笔记---第十三章:字符串
- Java编程思想笔记——第十三章 字符串
- 读书笔记 JAVA编程思想 第13章 字符串
- Java编程思想读书笔记——字符串
- java编程思想 第十三章 正则表达式
- Unity降低Draw Call
- 单链表-【学生信息管理系统】
- python numpy 显示图像阵列
- Atitit.eclipse 4.3 4.4 4.5 4.6新特性
- GreenDao3.0学习(三)
- java编程思想读书笔记 第十三章 字符串(上)
- CSS3_Node1_选择器&边框&阴影
- 适配器模式与Android中的Adapter
- 复制文件的问题:使用FileInputStream和FileOutputStream实现文件复制
- 文章标题
- 剑指offer(9)-树的子结构
- 回文序列-2017网易校园招聘
- 顺序表-【学生信息管理系统】
- Fast RCNN 训练自己数据集 (1编译配置)