这里我会围绕着字符串进行一些描述,内容借鉴《Java 编程思想》第四版
一、String
不可变的final类
每一次的String类的赋值、看起来的修改值的动作,实际上是创建了一个全新的String对象接收“修改”后的新值,而最初的那个String丝毫未变
public class changeDemo{
public static String upcase(String a) {
return a.toUpperCase();
}
public static void main(String[] args) {
String q = "happy";
System.out.println(q);
String qq = upcase(q);
System.out.println(qq);
System.out.println(q);
}
}
//以为的q被当做参数传递给upcase()方法,实则传递的是q引用的一个拷贝,“而该引用所指的对象其实一直呆在单一的物理位置上,从未动过”。
//局部引用a只有在upcase()方法被调用时才存在,方法返回的对象已经是个新的String对象,原来的q依然没有被改变过
★参数只用为传值,而非用于改变。可以简单的理解为,String对象,具有只读性。
★Java中“+”与“+=”是仅有的两个被重载的操作符,慎用它们。它们会产生一些意料之外的垃圾。
public class Demo {
public static void main(String[] args) {
String a = "a";
String b = a + "b" + "c" + "d";
System.out.println(b);
}
}
//看似简单的“+”动作形成最终的对象b,途中却一次一次的产生String对象。如果有很多的“+”动作,那么将会有大堆的垃圾等待被处理
★当然,编译器会自主选择更高效的StringBuilder对象,并调用其apend()方法将所有的String对象连接起来。但是这并不代表着你就可以随心所欲的使用String对象。假如在一个循环中使用String进行一些修改操作,那么将会有循环次数个StringBuilder会因此而被创建,又是垃圾。
二、StringBuilder
用StringBuilder代替String,将其对象放在循环中进行字符操作,只需要一个StringBuilder,再加上toString()方法,便是最终期待的那个String了。
public class Demo {
public String method(String[] things) {
StringBuilder sb = new StringBuilder();
for(int i=0;i<things.length;i++)
sb.append(things[i]);
return sb.toString();
}
}
//尝试用 javap -c className 来查看代码如何工作
★ StringBuilder,JDK1.5才开始有的一个StringBuffer类的简单替换者,效率高。这和它并不安全有关。它的方法有 insert()、repleace()、substring()、reverse()、delete()和常用的append()与toString()。
小心toString()中的陷阱。简单的字符串操作,编译器会给你构造合理出合理的结果,但是要
在其中使用循环,StringBuilder是不错的选择。但是StringBuilder也会有小埋伏,种种情况,
可以用javap进行代码分析
三、正则表达式
★正则表达式,简洁、动态的语言,提供了一种完全通用的方式来解决各种字符串相关的问题。但是其语法是个难点。
★JDK文档中的 java.util.regex.Pattern 会是一个不错的参考对象
★Pattern和Matcher
通过调用Pattern.matcher(),传入一个字符串,得到一个Matcher对象。再利用该对象的方法来进行不同的判断,从而知道正则表达式是否匹配成功。Matcher的几个方法:matches()、lookingAt()、find()、find(int start)都会返回布尔值,作用大家自己猜猜吧,要注意各个方法之间的差异才好
至于Matcher对象的一系列获取与 组 相关的信息的方法,大家可以去网上找找,我这里就不再写出来了(主要是觉得麻烦)。不过什么是组呢?组是用括号划分的正则表达式,可以根据租的编号来引用某个组,以书中的列子来说明:A(B(C))D ,组0为ABCD,组1为BC, 组2为C
至于Pattern,其compile()在接受标记参数后,该类中的常量就值得去熟悉了。比如说Pattern.CASE_INSENSITIVE、Pattern.MULTILINE、Pattern.COMMENTS,至于什么意思,再猜猜?哦,对了,接受参数后的compile()是这样的:compile(String regex,int flag)。至于怎么用,返回什么,继续猜?
★替换操作
替换操作会经常用到,相对而言方法使用起来比较直接。不过其中的appendReplacement(StringBuff sbuf,String replacement)方法比较有意思,渐进式替换,不会像replaceAll()什么的那么死板。你可以对replacement参数做改动。
StringBuffer sbuf = new StringBuffer();
Pattern p = Pattern.compile("[aeiou]");
Matcher m = p.matcher(....);
m.appendReplacement(sbuf,m.group().toUpperCase());
★正则表达式与 Java I/O
net.mindview.util.TextFile对象将文件打开读入并存储到一个ArrayList中
for(String line : new TextFile(那个文件名,那个匹配))
//如何获取所有文件的名字
File[] files = new File(".").listFiles();
字符串这个东西挺丰富,以前先入为主一味觉得String === 字符串,到后来慢慢了解多了,理解多了,才知道自己的井底之蛙。
随着越来越多的书本知识和拧螺丝发现,拧螺丝很重要,书本更重要。特别是我这种智商又不高(《Java编程思想》在看第二遍了,估计还得再看一遍,然后再看一遍?),长得又一般的人(玛德),不多看点书找到方向,一味跟着 “经验很重要,有经验不怕没人要” 的思想走,估计绕一圈又得绕回来:“你知道这个操作的实现原理是什么吗?”
不过Java这个东西真的很好玩啊。。。