可以证明,String操作是计算机程序设计中最常见的行为。——《Java编程思想》
我也可以证明,要想学好Java编程,必须得把String的马步给扎得稳稳的。之前,我自以为有了几年编程经验,觉得String这些老生常谈的话题(比如equals与==)可真是无聊!但事实并非如此,这些基础知识需要反复的传播和推广!
请允许我先举一个例子(请勿对号入座):
有小伙伴在沉默王二技术交流群里发了下面这样一幅图片,问:“我这样判断字符串为空 正确吗?”
我没敢轻易下结论,仔仔细细的看了好一遍;先判null,之后把entName放在equals的参数位置判空,我觉得这位小伙的代码写得很完美啊。
但意想不到的是,小伙伴紧接着说:“但是我调试,是null的时候还是进入if ”。 我当时回答说:“那你的调试肯定是瞎调,或者见鬼了。嘿嘿”
我当时诧异极了。幸好之后小伙伴发来debug的截图!
你说呢,这样写不报错才怪! 之后我稍解释了一番,并回复说:“建议啊,不是我打击啊,还是多扎扎马步比较好”。 下面我们就细致来说一下String不得不明白的3个点。
如上文提到的,检查String是否相等最好要使用equals方法,尽量少使用==操作符。
String cmower ="cmower"; System.out.println("cmower" == cmower);//true System.out.println("cmower".equals(cmower));//true System.out.println("cmower".substring(0, 3) == "cmo");//false System.out.println("cmower".substring(0, 3).equals("cmo"));//true ==操作符确定的是两个String是否放在同一个位置上。“cmower”字符串和cmower变量指向的引用就是在同一个位置上,所以==比较结果为true。在Java虚拟机上,只有字符串常量是共享的(”cmower”字符串和cmower变量共享了同一个地址)。但是对于substring产生的结果就不共享了。对于equals,比较的则是两个对象是否具有相同的字符集。Compares this string to the specified object. The result is true if and only if the argument is not null and is a String object that represents the same sequence of characters as this object.
“s”是一个字符串对象,你怎么也不能把这个对象变成“S”。也就是说小s和大S尽管是双胞胎,但她们俩注定都不能成为对方。
首先,我们先来看对于+操作符,在Java虚拟机下是如何工作的。
public static String add1() { String b = "b"; String s = "a" + b + "c" + "d" + 100; return s; } public static String add2() { String s = "a" + "b" + "c" + "d" + 100; return s; }对于add1和add2方法,你认为Java虚拟机的工作方式一样吗?
闭上眼睛10秒钟,先想一会。
我们来揭晓答案:
差别是不是很大?
这说明,+操作符在拼接String时,会根据情况做一定的选择。比如add1方法,Java会new 一个StringBuilder对象,来对abcd100进行append操作,之后再toString出来。
那么也就说,Java会自动会为我们优化代码,以后我们尽管使用+操作符就行了。但事实并非如此,再来看一串代码。
public static String plus() { String result = ""; for (int i = 0; i < 10; i++) { result += "a"; } return result; } public static String sb() { StringBuilder sb = new StringBuilder(); for (int i = 0; i < 10; i++) { sb.append("a"); } return sb.toString(); }这个时候,你选择用sb方法还是plus方法?
再闭上眼睛10秒钟,想一下你的答案。
javap执行结果如下:
看得出plus方法的8-34行是一个循环,11行时创建了StringBuilder对象,也就是在循环内。这个方法执行了10次,那么也就创建了10个StringBuilder对象。
再来看sb方法的结果:
显而易见,StringBuilder对象只有一个。
在使用StringBuilder时,尽量少“在append方法的参数中使用+操作符”:
public static String sb1() { StringBuilder sb = new StringBuilder(); String b = "b"; for (int i = 0; i < 10; i++) { sb.append("a" + b); } return sb.toString(); }这样做糟糕至极:
“a” + b时又重新创建了StringBuilder对象。
总结如下, 1. 在进行循环多次拼接String时,用StringBuilder而不用+操作符! 2. +操作符只用于少量字符串变量拼接,在内存中操作,性能更高! 3. append方法的参数少用+操作符!
最后,留一个话题讨论一下。 对于substring(int beginIndex, int endIndex)方法,在《Java核心技术卷1》上说,endIndex指的是不想复制的第一个位置。但这句话很拗口。我自己也经常搞不清楚到底endIndex该为多少,总是怕搞错,最后非要输出结果确认一下!
问:“如何更好的确定endIndex?”
"cmower".substring(0, 3);关注“沉默王二”公众号,与你分享IT干货 · 生活感悟 · 读书心得;还有《声音驿站》等着你! 微信扫一扫下方二维码即可关注:
沉默王二 认证博客专家 博客之星 Java 大牛 微信搜索【沉默王二】,回复关键字【Java】白嫖1000本精华电子书。我的微信:qing_geee 有任何问题欢迎私聊咨询。