JAVA编程思想学习笔记(十四)字符串

字符串

  • 不可变的String
  • 重载“+”与StringBuilder
    • 无意识的递归
  • 格式化输出
    • Formatter类
    • String.format()
    • 正则表达式
    • Pattern和Matcher
    • split
    • 替换操作
    • reset

不可变的String

对于很多初学者来说,可能会没有感觉到String不可变这件事,下面给个例子先体会下:

class T{
	int a;
	T(int a){
		this.a = a;
	}
	
}
public class TestString {
	
	public static String fun(String s){
		return s = "fun";
	}
	public static T fun(T s){
		s.a = 0;
		return s;
	}
	public static void p(String s){
		System.out.println(s);
	}
	
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String ss = "ss";
		String s = fun(ss);
		p("s:"+s);//不建议这么用
		p("ss:"+ss);
		T tt = new T(1);
		T t = fun(tt);
		p("t:"+t.a);
		p("tt:"+tt.a);
		
	}

}

这里用了另一个类的对象做比较,会发现,一般的对象都会被改变,但是String的对象却不会。
实际上每一个看似修改String的操作,实际上都是重新创建了个String对象,以包含修改后的字符串内容。而最初的String对象却丝毫未动。

重载“+”与StringBuilder

java中仅有的两个重载过的操作符是“+”和”+=“。在我们使用重载符的时候,具体是怎么工作的呢?
在我们使用”+“的时候,编译器会自动的创建一个StringBuilder对象,用以构造最终的String,并为字符串调用StringBuilder的append()方法,最后调用toString()生成结果。
现在,也许你会觉得这样就可以随意的使用String对象了,反正编译器会自动优化,可是实际上,编译器优化的能力也是有限的,不如自己使用StringBuilder。

无意识的递归

当我们想要输出一个类的地址时怎么办呢?
你可能会觉得很简单,用this关键字就可以。但是你会发现,这样会产生很长的异常。
究其原因,因为编译器看到一个String对象后面跟着一个“+”,而再后面的对象不是String,于是编译器试着将this转换成一个String类型,怎么转换呢,正是通过调用this的toString方法,于是就发生了递归调用。

格式化输出

format()方法模仿自c语音的printf,举个简单的例子:

public static void main(String[] args) {
		// TODO Auto-generated method stub
		System.out.format("%d,%f", 1,0.01);
		
	}

Formatter类

在java中所有格式化功能都由Formatter类处理,可以将Formatter看做一个翻译器,当你创建Formatter对象的时候,需要指出向哪里输出,下面有个例子可以很清晰的看出来:

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		PrintStream out = System.out;
		Formatter f =new Formatter(out);
		f.format("%d,%f", 1,0.01);
	}

常用类型转换表如下:
JAVA编程思想学习笔记(十四)字符串_第1张图片

String.format()

String.format()是一个static方法,返回String对象,用法和上文类似,下面是个例子:

public class TestStringFormat {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String a="a";
		String b="b";
		int c = 1;
		String test = String.format("%s+%s=%d", a,b,c);
		System.out.println(test);
	}

}

正则表达式

JAVA编程思想学习笔记(十四)字符串_第2张图片
JAVA编程思想学习笔记(十四)字符串_第3张图片
JAVA编程思想学习笔记(十四)字符串_第4张图片
量词:

  • 贪婪型:量词总是贪婪的,除非有其他的选项被设置,贪婪表达式会为所有可能的模式发现尽可能多的匹配。
  • 勉强型:用问号来指定,这个量词匹配满足模式所需的最少字符数。
  • 占有型:当正则表达式被应用于字符串时,它会产生更多的状态,以便匹配失败时回溯,而占有型并不保存这些中间状态,因此可以防止回溯,这么做的目的,是防止正则表达式失控,因此执行起来跟有效。

JAVA编程思想学习笔记(十四)字符串_第5张图片

Pattern和Matcher

一般来说,比起功能有限的String类,我们更愿意使用正则表达式,我们只需要导入java.util.regex包,然后使用Pattern.compile方法来编译你的正则表达式即可,它会根据你的String类型的正则表达式生成一个Pattern对象,接下来,把你想要检索的字符串传入Pattern对象的matcher方法,该方法会生成一个Matcher对象,它有很多功能可用。

public class TestPattern {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String[] test = {"a","abc","bcd","bc","a","b"};
		for(String t:test){
			Pattern p = Pattern.compile("a+");
			Matcher m = p.matcher(t);
			while(m.find()){
				System.out.println(t+":"+m.group());
			}
		}
	}

}

输出:

a:a
a:a
b:b

split

split方法将输入字符串断开成字符对象数组,断开边界由正则表达式确定。
有一个快速而方便的方法,可以按照通用边界断开输入文本:

public class TestPattern {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		String test = "ab!cabccc!aabca";
		String[] tests = Pattern.compile("!").split(test);
		for(String t:tests){
			System.out.print(t+",");
		}
		
	}

}

输出:

ab,cabccc,aabca,

替换操作

替换操作比较简单,String有replaceAll方法,可以将所有字符进行替换,下面有个简单的例子:

public class TestPattern {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String content = "a sd df !He is Tom,Tom fall in love with Jery! fg jjk kl";
		Pattern p = Pattern.compile("!(.*)!");
		Matcher m = p.matcher(content);
		if(m.find()){
			content = m.group(1);
			content = content.replaceAll("Tom", "Marry");
		}
		System.out.println(content);
	
	}

}

输出:

He is Marry,Marry fall in love with Jery

reset

可以将现有的Matcher对象应用于一个新的字符序列:

public class TestPattern {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String content = "a sd df !He is Tom,Tom fall in love with Jery! fg jjk kl";
		String content2 = "a sd df !She is Tom,Tom fall in love with Jery! fg jjk kl";
		Pattern p = Pattern.compile("!(.*)!");
		Matcher m = p.matcher(content);
		if(m.find()){
			content = m.group(1);
			content = content.replaceAll("Tom", "Marry");
		}
		
		m.reset(content2);
		if(m.find()){
			content = m.group(1);
			
		}
		
		System.out.println(content);
	
	}

}

输出:

She is Tom,Tom fall in love with Jery

你可能感兴趣的:(学习笔记)