Thinking in Java
字符串
1、在Java中,对字符串的操作主要集中在
String,StringBuffer(StringBulider),StringTokenizer类;
2、String的不可改变性:
(1)String对象具有只读特性,所以指向它的任何引用都无法改变它的值;
(2)所有针对修改String的方法,
实际是创建了一个新的String对象,以包含修改后的字符串内容,原来的String对象被保留;
(3)在使用String进行各修改时,编译器会自动选择构造中间String,或者StringBuffer(Java SE5前)对象;
在编写toString方法时,如果字符串比较简单,可以信赖编译器自动选择构造方式,
如果要在toString()方法中使用循环,那最好自己创建一个StringBuffer或StringBuilder,因为自动选择构造器时,当toString拥有循环,会创建多个StringBuffer对象,导致开销过大;
(4)
StringBuffer:Java SE5前的默认自动构造器,线程安全,开销较大;
StringBuilder:Java SE5引进的默认自动构造器,线程不安全,但是运行效率较高;
※Java不允许运算符重载,用于String的“+”和“+=”是Java仅有的两个重载过的运算符;
※
使用JDK自带的工具javap可以对.java文件进行反编译,生成字节码:
javap -c Classname;
※打印对象的内存地址:
通过调用Object类的toString()方法;
class AObject{
public String getAddress(){ return super.toString(); }
public static void main(){
AObject obj = new AObject();
System.out.println(obj.getAddress());S
}
}
3、格式化输出
(1)System.out
.println(formatString,parameter);
(2)String
String.format(formatString,paremeter);
(3)使用java.util.Formatter类;
Formatter
formatter = new Formatter();
String str =
formatter.format(formatStrig,paremeter);
(4)格式化说明符
%[argumnet_index$][flags][width][.precision]conversion
argumnet_index$:表示该conversion在后面参数列表中的位置,为一个从1开始的十进制数,如:2$;
flags:修改输出格式的字符集;
width:输出最小宽度;
.precision:Sting表示输出字符的最大数量,浮点数表示小数位(不足补0);
conversion参数
如:String.format("%2$-05.3f" , 20.1, 10.24);
输出:00010.240,左对齐;
※在功能相同的情况下,String.format()方法比Formatter.format()成员方法效率更高;
正则表达式
1、正则表达式是一种强大而灵活的文本处理工具,很久就集成到标准Unix工具集中(如sed和awk),以及程序设计语言中(如Python和Perl);
2、Java中与正则表达式关联的String类工具:
(1)bolean String.
matches(String regex) 成员方法:匹配正则表达式;
(2)String[] String.
split(String regex,[int limitNum]) 成员方法:使用正则表达式分割String;
(3)String String.
repalceAll(regex,String replacement) 成员方法:使用replacement替换字符串中的所有regex匹配项;
String String.
replaceFirst(regex,replacement) 成员方法:
3、创建正则表达式
补充表:
如:(^[aeiou]|(\s+[aeiou]))\w+?[aeiou]\b 同\b([aeiou])\w+?[aeiou]\b
匹配以元音字母开头,同时以元音字母结尾的单词,捕获组为开头和结尾的元音字母;
^J...A$匹配:J_ _ _ A型的字符串;
※
通常表达式X必须要用()修饰,以便按照期望的效果区执行;
abc+:先匹配ab,在匹配c至少一次;
(abc)+:匹配abc至少一次;
※
在Java中使用正则表达式时,注意要对\进行转义,如\w在Java中:String pattern = “\\w”;
4、量词
量词描述了一个模式吸收输入文本的方式;
(1)Greedy(贪婪型):默认量词吸收方式,先将整个字符串会吞下,在匹配整个字符串,如果不配,就从右端吐出一个字符,继续匹配;
(2)Reluctant(勉强型):先从左端吞入一个字符,进行匹配,若不匹配就再吞入一个字符继续匹配;
(3)Possessive(占有型):目前这种模式只在Java中使用,当正则表达式被应用字符串时,会产生很多的状态,以便在回溯失败时得以回溯,“占有的”量词不保存这些中间状态,由此防止回溯,可以使正则表达式执行起来更加高效;
5、CharSequence接口
CharSequeue接口从
CharBuffer,String,StringBuffer,StringBuilder类之中抽象出了字符序列的一般化定义(这些类都实现了该接口):
interface CharSequence{
charAt(int i);
length();
subSequecne(int start,int end);
toString();
}
多数正则表达式的操作都接受CharSequence类型的参数;
6、Pattern和Matcher类
可以使用
java.util.regex包中的
Pattern,Matcher构建功能比String更加强大的正则表达式对象;
import java.util.regex;
Pattern p = Pattern.complie(String regex); //构建正则表达式对象
Matcher m = p.matcher(String targetString); //构建正则表达式对目标字符串的匹配对象
boolean b = m.matches();
while(m.find()){
println("Match "+m.group()+"at position "+m.start()+" to "+(m.end()-1));
}
//m.find():扫描输入序列于该模式匹配的下一个子序列;
//m.group():返回该匹配子序列,m.group(int index)返回指定次序目标的匹配子序列,由捕获组区分,从1开始;
//m.start() m.end():返回该子序列在目标串中的位置下标;
7、使用正则表达式扫描固定格式文本
①一般从文件或标准输入流读取数据的思路:
读入一行文本,对其进行分词,然后使用Integer、Double等类的各种解析方法解析数据;
②对于固定格式文本,可以使用正则表达式对文本进行扫描;
String data = “58.27.82.162@02/10/2016\n”+......;
Scanner scanner = new Scanner(data); //使用扫描器扫字符串;
String pattern = "(\\d+[.]\\d+[.]+\\d+[.])@"+"\\d{2}/\\d{2}/\\d{4}";
while(scanner.hasNext(pattern)){ //当扫描器中还有匹配项,执行以下;
scanner.next(pattern); //扫描器扫描下一个匹配项;
java.util.regex.MatchResult mactch = scanner.mactch(); //由扫描器创建的当前匹配对象(Matchresult extends Match)
String ip = match.group(1); //获取匹配对象中的捕获组;
String date = match.group(2);
}