【Java】字符串String操作

Java中的字符采用Unicode编码。Java SE提供了三个字符串类:String,StringBuffer,StringBuilder。String是不可变字符串,StringBuffer和StringBuilder是可变字符串。

1.不可变字符串String

很多计算机语言都提供了两种字符串,即不可变字符串和可变字符串,它们的区别在于当字符串进行拼接等修改操作时,不可变字符串会创建新的字符串对象,而可变字符串不会创建新对象。

Java中不可变字符串类是String,属于java.lang包。在使用java.lang包中的类时不需要引入(import)该包,因为它是由解释器自动引入的。

1.1创建字符串对象

public class stringCreate {

	public static void main(String[] args) {
		//创建字符串对象
		String s1=new String();
		String s2=new String("Hello World");
		System.out.println("s1="+s1);
		System.out.println("s2="+s2);
		
		char chars[]= {'a','b','c','d','e'};
		//通过字符数组创建
		String s3=new String(chars);
		//通过子字符数组创建字符串对象
		String s4=new String(chars,1,4);	//1是数组第一个字符的索引,4是指定子数组的长度
		System.out.println("s3="+s3);
		System.out.println("s4="+s4);
		
		byte bytes[]= {97,98,99};
		//通过byte数组创建字符串对象
		String s5=new String(bytes);
		System.out.println("s5="+s5);
		System.out.println("s5字符串长度="+s5.length());
	}
}

运行结果:

1.2字符串池

public class stringCreate {

	public static void main(String[] args) {
		
		String s6=new String("Hello");	//使用new关键字创建
		String s7=new String("Hello");
		
		String s8="Hello";	//字符串常量
		String s9="Hello";
		
		System.out.printf("s6==s7:%b\n",s6==s7);
		System.out.printf("s8==s9:%b\n",s8==s9);
		System.out.printf("s6==s8:%b\n",s6==s8);
		System.out.printf("s7==s8:%b\n",s7==s8);
	}
}

运行结果:

==比较的是两个引用是否指向相同的对象,从上面结果可见,通过new关键字创建的对象指向的是不同对象,使用字符串常量创建的指的是相同对象。

这是因为Java中的不可变字符串String常量采用字符串池(String Pool)管理技术,字符串池是一种字符串驻留技术。采用字符串常量赋值时,会在字符串池中查找字符串常量,如果已经存在,则把引用赋值给当前创建的字符串常量,否则创建字符串对象,并放到池中。

1.3字符串拼接

String字符串虽然是不可变字符串,但也可以进行拼接,只是会产生一个新的对象。String字符串拼接可以使用+运算符或String的concat(String str)方法。+运算符的优势是可以连接任何类型数据拼接成为字符串,而concat方法只能拼接String类型字符串。

public class stringConcat {

	public static void main(String[] args) {
		String s1="Hello";
		//使用+运算符连接
		String s2=s1+" ";
		String s3=s2+"World";
		System.out.println(s3);
		
		String s4="Hello";
		//使用+运算符连接,支持+=赋值运算符
		s4+=" ";
		s4+="World";
		System.out.println(s4);

		String s5="Hello";
		//使用concat方法连接
		s5=s5.concat(" ").concat("World");
		System.out.println(s5);
		
		java.util.Date now=new java.util.Date();
		//对象拼接自动调用toString()方法
		String s6="今天是:"+now;
		System.out.println(s6);
	}
}

运行结果:

Java中所有对象都有一个toString()方法,该方法可以将对象转换为字符串,拼接过程会调用该对象的toString()方法,将该对象转换为字符串后再进行拼接。

1.4字符串查找

在给定的字符串中查找字符或字符串是比较常见的操作。在String类中提供了indexOf和lastIndexOf方法用于查找字符或字符串,返回值是查找的字符或字符串所在的位置,-1表示没有找到。

字符串本质上是字符数组,因此它也有索引,索引从零开始。String的charAt(int index)方法可以返回索引index所在位置的字符。

public class stringSearch {

	public static void main(String[] args) {
		String sourceStr="There is a string accessing example.";
		
		//获得字符串长度
		int len=sourceStr.length();
		
		//获得索引位置16的字符
		char ch=sourceStr.charAt(16);
		
		//查找字符和子字符串
		int firstChar1=sourceStr.indexOf('r');
		int lastChar1=sourceStr.lastIndexOf('r');
		int firstStr1=sourceStr.indexOf("ing");
		int lastStr1=sourceStr.lastIndexOf("ing");
		int firstChar2=sourceStr.indexOf('e',15);
		int lastChar2=sourceStr.lastIndexOf('e',15);
		int firstStr2=sourceStr.indexOf("ing",5);
		int lastStr2=sourceStr.lastIndexOf("ing",5);
		
		System.out.println("原始字符串:"+sourceStr);
		System.out.println("字符串长度:"+len);
		System.out.println("索引16的字符:"+ch);
		System.out.println("从前往后搜索r字符,第一次找到它所在的索引:"+firstChar1);
		System.out.println("从后往前搜索r字符,第一次找到它所在的索引:"+lastChar1);
		System.out.println("从前往后搜索ing字符串,第一次找到它所在的索引:"+firstStr1);
		System.out.println("从后往前搜索ing字符串,第一次找到它所在的索引:"+lastStr1);
		System.out.println("从索引为15位置开始,从前往后搜索e字符,第一次找到它所在索引:"+firstChar2);
		System.out.println("从索引为15位置开始,从后往前搜索e字符,第一次找到它所在索引:"+lastChar2);
		System.out.println("从索引为5位置开始,从前往后搜索ing字符串,第一次找到它所在索引:"+firstStr2);
		System.out.println("从索引为5位置开始,从后往前搜索ing字符串,第一次找到它所在索引:"+lastStr2);
	}
}

运行结果:

1.5字符串比较

字符串比较包括比较相等,比较大小,比较前后缀等。

比较前缀和后缀;

boolean endsWith(String suffix):测试此字符串是否以指定的后缀结束。

boolean startsWith(String suffix):测试此字符串是否以指定的前缀开始。

public class stringCompare {

	public static void main(String[] args) {
		String s1=new String("Hello");
		String s2=new String("Hello");
		//比较字符串是否是相同的引用
		System.out.println("s1==s2:"+(s1==s2));
		//比较字符串内容是否相等
		System.out.println("s1.equals(s2):"+(s1.equals(s2)));
		
		String s3="HELLO";
		//忽略大小写比较字符串内容是否相等
		System.out.println("s1.equalsIgnoreCase(s3):"+(s1.equalsIgnoreCase(s3)));
		
		//比较大小
		String s4="java";
		String s5="Swift";
		//比较字符串大小 s4>s5
		System.out.println("s4.compareTo(s5):"+(s4.compareTo(s5)));
		//忽略大小写比较字符串大小 s4<s5
		System.out.println("s4.compareToIgnoreCase(s5):"+(s4.compareToIgnoreCase(s5)));
	}
}

运行结果:

1.6字符串截取

public class stringCut {

	public static void main(String[] args) {
		String sourceStr="There is a string accessing example.";
		
		//截取example.子字符串
		String subStr1=sourceStr.substring(28);
		//截取string子字符串
		String subStr2=sourceStr.substring(11,17);
		System.out.printf("subStr1=%s%n",subStr1);
		System.out.printf("subStr2=%s%n", subStr2);
		
		//使用split方法分隔字符串
		System.out.println("-----使用split方法-----");
		String[] array=sourceStr.split(" ");
		for(String str:array)
		{
			System.out.println(str);
		}
	}
}

 

2.可变字符串StringBuffer和StringBuilder

Java提供了两个可变字符串类StringBuffer和StringBuilder。也叫“字符串缓冲区”。

StringBuffer是线程安全的,它的方法支持线程同步,线程同步会操作串行顺序执行,在单线程环境下会影响效率。StringBuilder是StringBuffer的单线程版本,它不是线程安全的,但它的执行效率很高。

(线程同步是一个多线程概念,就是当多线程访问一个方法时,只能由一个优先级别高的线程先访问,在访问期间会锁定该方法,其他线程只能等到它访问完成释放锁,才能访问。)

StringBuffer和StringBuilder具有完全相同的API,即构造方法和普通方法等内容一样。

2.1字符串长度和字符串缓冲区容量

字符串长度是指在字符串缓冲区中目前所包含的字符串长度,通过length()获得;

字符串缓冲区容量是缓冲区中所能容纳的最大字符数,通过capacity()获得。

字符串缓冲区容量默认值是16,达到最大容量的时候,它会将自身容量增加到当前的2倍再加2。而初始化长度=默认值+参数长度。看下面一个例子:

package builder;
public class LengthAndCapacity {

	public static void main(String[] args) {
		StringBuilder sbuilder1=new StringBuilder();
		System.out.println("包含的字符串长度:"+sbuilder1.length());
		System.out.println("字符串缓冲区容量:"+sbuilder1.capacity());
		
		StringBuilder sbuilder2=new StringBuilder("hello");
		System.out.println("包含的字符串长度:"+sbuilder2.length());
		System.out.println("字符串缓冲区容量:"+sbuilder2.capacity());
		
		//字符串缓冲区初始容量是16,超过之后会扩容。
		StringBuilder sbuilder3=new StringBuilder();
		for(int i=0;i<17;i++)
		{
			sbuilder3.append(8);
		}
		System.out.println("包含的字符串长度:"+sbuilder3.length());
		System.out.println("字符串缓冲区容量:"+sbuilder3.capacity());
	}

}

运行结果: 

2.2字符串追加

package builder;
public class StringAppend {

	public static void main(String[] args) {
		StringBuilder sbuilder1=new StringBuilder("hello");
		sbuilder1.append(" ").append("world");
		sbuilder1.append(".");
		System.out.println(sbuilder1);
		
		StringBuilder sbuilder2=new StringBuilder();
		Object obj=null;
		//添加布尔值,转义符和空对象
		sbuilder2.append(false).append('\t').append(obj);
		System.out.println(sbuilder2);
		
		StringBuilder sbuilder3=new StringBuilder();
		for(int i=0;i<10;i++)
		{
			sbuilder3.append(i);
		}
		System.out.println(sbuilder3);
	}
}

运行结果:

2.3字符串插入,删除和替换

package builder;

public class InsertDeleteReplace {

	public static void main(String[] args) {
		//原始不可变字符串
		String str1="Java C";
		//从不可变的字符串创建可变字符串对象
		StringBuilder mstr=new StringBuilder(str1);
		
		//插入字符串
		mstr.insert(4," C++");	//在索引为4的字符位置之前插入" C++"
		System.out.println(mstr);
		
		//具有追加效果的插入字符串
		mstr.insert(mstr.length()," Objective-C");
		System.out.println(mstr);
		
		//追加字符串
		mstr.append(" and Swift");
		System.out.println(mstr);
		
		//删除字符串
		mstr.delete(11,23);	//删除指定索引范围内的字符(包含头不包含尾)
		System.out.println(mstr);
	}

}

 运行结果:

猜你喜欢

转载自blog.csdn.net/shimadear/article/details/86541559