12,String、StringBuffer和StringBuilder
13.1 String类
字符串类,内部封装了对字符串进行操作的方法.方便对字符串类型数据的操作.
注意:
1,因为String类是引用数据类型,把一个字符串赋值给引用数据类型,那么这个字符串就是一个对象.
2,字符串一旦被初始化,就不能被改变.
如:
public class StringDemo {
public static void main(String[] args) {
String str1="abc";
String str2="abc";
System.out.println(str1==str2);
System.out.println(str1.equals(str2));
}
}
/*
*打印结果:
true
true
*/
字符串对象存储在字符串常量池中,且一旦初始化就不能被改变。
str1==str2,比较的是对象的地址,结果:true,是因为str1在字符串常量池中创建了"abc"字符串对象,字符串常量池的特点是:没有就创建,如果有就直接使用.所以,str2="abc",实际上就是指向了同一个字符串,"abc".两个引用型变量指向同一个字符串,所以地址相同.
而str1.equals(str2),调用的实际上是String类覆写Object类的equals()方法,在String类中定义了equals()方法的特定比较方式,就是比较字符串的内容,不再是像Object()中的equals()方法,比较的是地址.
如:
public class StringDemo {
public static void main(String[] args) {
String str1="abc";
String str2=new String("abc");
System.out.println(str1==str2);
System.out.println(str1.equals(str2));
}
}
/*
*打印结果:
false
true
*/
String str1="abc";
String str2=new String("abc");
System.out.println(str1==str2);
为什么这种创建方式,地址比较结果是 false呢?两者有何区别?
首先,String str1="abc";是在字符串常量池中创建对象,只创建了一个对象.
而,String str2=new String("abc");使用new创建的对象,是在堆内存中创建的对象,且创建的是是两个对象.
所以,两者的地址是不同的.
System.out.println(str1.equals(str2));这里比较的是两个对象的字符串内容,所以结果为true.
13.2 String类的构造函数和一般函数
String类中的构造函数,可以接收,byte[],char[],int[]这些类型的数组,及数组的一部分,把数组转换成String类型.方便使用String类中的方法,对这些数组进行操作.
String类中的一般函数,按函数的作用分为:获取、转换、判断、比较。
如:获取字符串的字符个数、根据位置获取字符、根据字符获取在字符串第一次出现的位置等等。
示例代码:
1.获取
public class StringDemo {
public static void main(String[] args) {
//1,字符串构造函数的使用.
byte[]arr1={2,33,44,55,33,55,35,6};
int[] arr2={13,2,5,0,34,4343,45,33};
char[]arr3={'a','A','b','B','c','C','d','D'};
String str1=new String();//创建字符对象,不传入参数.
String str2=new String(arr1);//创建字符串对象,传入byte型数组.
String str3=new String(arr2,0,arr2.length);//创建字符串对象,传入int型数组.
String str4=new String(arr3);//创建字符串对象,传入char型数组.
String str5="abceabcdafafafaghhhh";
//2,String类中的获取方法
//获取字符串中字符的个数
System.out.println(str5.length());//结果:20
//根据指定位置获取字符,字符串中字符的起始位置从0开始.
System.out.println(str5.charAt(3));//结果:e
//根据字符获取在字符串中第一次出现的位置(注意如果字符找不到时,返回-1)
System.out.println(str4.indexOf('c'));//结果:4
//从后往前索引指定字符或字符串第一次出现的位置
System.out.println(str4.lastIndexOf('b'));//2
System.out.println(str4.lastIndexOf('b', 8));//从指位置开始索引
System.out.println(str5.lastIndexOf("bc"));//5
System.out.println(str5.lastIndexOf("bc", 3));//从指定位置开始索引: 1
//获取字符串指定起始到指定结束位置的子串,包含头不包含尾。
System.out.println(str5.substring(2, 8));//此方法,包含头,不包含尾。
System.out.println(str5.substring(2));//没有指定结尾,代表以字符串长度为准,相当于str5.subString(2,str5.length())
}
}
2.转换
public class StringDemo {
public static void main(String[] args) {
String str="ab1cdefg3hilj4klp3kl";
Demo_2(str);
}
//演示转换方法
public static void Demo_2(String str) {
//1,将一个字符串,按照正则表达式,转成字符串数组
String[]strs=str.split("\\d");// 此正则表达式代表0-9数字
//2,将一个字符串,转换成字符数组.
char[]chs=str.toCharArray();
//3,将一个字符串,转换成字节数组.
byte[]byts=str.getBytes();
//4,将一个字符串中的字符转成大写或小写
System.out.println(str.toUpperCase());//转成大写AB1CDEFG3HILJ4KLP3KL
System.out.println(str.toLowerCase());//转成小写ab1cdefg3hilj4klp3kl
//5,替换字符串中的指定内容
System.out.println(str.replace('a', 'A'));//Ab1cdefg3hilj4klp3kl
System.out.println(str.replace("kl", "LK"));//ab1cdefg3hilj4LKp3LK
System.out.println(str.replaceAll("\\d", "0"));//使用正则表达式,只要匹配正则的字符,都会被替换.
//6,去除字符串两端的空格
str.trim();
//7,将字符串和指定字符串连接.
System.out.println(str.concat("12345"));//ab1cdefg3hilj4klp3kl12345
//8,将接收的数据类型转成字符串类型
System.out.println(str.valueOf(2));//”2”
}
}
3,判断
public class StringDemo {
public static void main(String[] args) {
String str="ab1cdefg3hilj4klp3kl";
Demo_3(str);
}
//演示判断的方法
public static void Demo_3(String str) {
//1,判断字符串与指定字符串是否相等,判断内容。
System.out.println(str.equals("abc"));
//2,判断字符串是否以指定字符串开始或结束。
System.out.println(str.startsWith("ab"));
System.out.println(str.endsWith("kl"));
//3,判断字符串是否包含指定的字符串
System.out.println(str.contains("abc"));
}
}
4.比较
public class StringDemo {
public static void main(String[] args) {
String str="abcccc";
Demo_4(str);
}
//演示比较的方法
public static void Demo_4(String str) {
//1,比较两个字符串的大小和是否相等。
System.out.println(str.compareTo("abcc"));
//比指定字符串大,返回大于0的数,比指定字符串小,返回小于0的数,相等,返回0。
}
}
练习1:将字符串"aabcjklmouial"进行反转。
思路:
1,将字符串反转需要操作元素的角标.
2,可以将字符串转成字符数组,然后对数组中的角标进行操作,使用第三方变量完成元素位置互换.
示例代码:
public class StringDemo {
public static void main(String[] args) {
String str="aabcjklmouial";
System.out.println(reverseString(str));//打印结果:laiuomlkjcbaa
}
public static String reverseString(String str) {
//1,将字符串转成字符数组
char[]chs=str.toCharArray();
//2,遍历字符数组,操作角标并完成元素位置互换
for (int start= 0,end=chs.length-1; start<end; start++,end--) {
swap(chs,start,end);//将元素位置交换的内容封装。
}
returnnew String(chs);//将数组转成字符串返回。
}
private static void swap(char[] chs, int start, int end) {
char temp=chs[start];//使用第三方变量完成元素位置操作。
chs[start]=chs[end];
chs[end]=temp;
}
}
练习2:获取一个字符串在另一个字符串中出现的次数
思路:
1, 要获取次数,肯定要有计数器。
2,可以使用indexOf(String s)方法,只要返回值不是-1,就代表找到,count就计数1次。并继续获取,但是要从字符串中减去指定字符串的长度,循环获取,直到返回-1,将count的值返回。
示例代码:
package字符串类;
public class StringDemo {
public static void main(String[] args) {
String str="abcllkjkiooomklabclkooabc";
String key="abc";
int count=getCount(str,key);
System.out.println("出现的次数:"+count); //出现的次数:3
}
public static int getCount(String str1, String key) {
int count=0;//定义一个计数器
int index=0;//定义一个变量,记录找到的字符串的位置。
while((index=str1.indexOf(key))!=-1){
str1=str1.substring(index+key.length());//找到后,要继续找,就要从找的的位置+字符串长度开始往后找,一直循环。
count++;
}
return count;//最后,返回次数。
}
}
练习3,获取两个字符串中的最大相同子串。
public class StringDemo {
public static void main(String[] args) {
String s1="akioeyfmvnvbnmop";
String s2="mvnvmopqs";
String maxString=getMaxString(s1,s2);
System.out.println("最大相同子串:"+maxString);//最大相同子串:mvnv
}
public static String getMaxString(String s1, String s2) {
for (int x = 0; x < s2.length(); x++) {//外循环按照S2的长度遍历。
for (int y =0,z=s2.length()-x; z!=s2.length()+1; y++,z++) {//内循环对说S2字符串递减
String sub=s2.substring(y,z);
if(s1.contains(sub)){
return sub;
}
}
}
return null;
}
}
13.2 StringBuffer和StringBuilder(字符串缓冲区)
StringBuffer(jdk 1.0 出现)和StringBuilder(jdk 1.5出现)的用法是完全一样的,但是,StringBuffer是支持多线程同步的,而StringBuiler是不同步的,StringBuilder效率相对StrinbBuffer要高,所以,一般用StringBuilder。
jdk升级的目的:1,简化书写。2,提高效率。3,增加安全性。
字符串缓冲区的特点:
1, 可以存储不同类型的数据
2, 长度是可变的,内部维护了一个可变长度数组。
3, 最终返回的都是字符串。
字符串缓冲区就是存储字符串的容器,相比较数组来说,与数组有区别
1, 数组只能存储同一类型数据,而字符串缓冲区可以存储不同类型数据。
2, 数组的长度是固定的,而字符串缓冲区是可变长度的。
StringBuilder类中,提供了增删改查的方法。
如:append(),insert(),delete(int start,int end),deleteCharAt(int indext),indexOf(String str),lastIndexOf(String str)等等。
示例代码:
public class StringDemo{
public static void main(String[]args){
StringBuilder sb=new StringBuilder("abcdlefghijkllmn");
demo_1(sb);
}
public static void demo_1(StringBuilder sb) {
System.out.println(sb.append("1234"));//append()方法的可以接收很多类型的参,依次从结尾添加。abcdefghijklmn1234
System.out.println(sb.insert(2, "22"));//在指定角标位置插入,指定类型数据。ab22cdefghijklmn1234
System.out.println(sb.indexOf("1234"));//获取指定数据在缓冲区中第一次出现的位置。16
System.out.println(sb.replace(0, 2, "000000"));//将缓冲区中指定范围的元素,替换成指定的数据。00000022cdefghijklmn1234
System.out.println(sb.lastIndexOf("l"));//从后往前索引指定数据,在缓冲区第一次出现的位置。19
sb.setCharAt(0, 'A');//修改指定位置上的元素为指定的内容。
System.out.println(sb);//A0000022cdlefghijkllmn1234
System.out.println(sb.substring(0,10));//将缓冲区的内容截取为一个子串。A0000022cd(包含头,不包含尾)
System.out.println(sb.reverse());//反转缓冲区中的内容。
System.out.println(sb.delete(0,10)); //删除缓冲区中指定范围的内容,start~(end-1)
}
}
面试题:
1,以下代码打印的结果:
public class Demo{
public static void main(String[] args) {
String str="ABCDEFG";
str.substring(3);
str.concat("123");
System.out.println(str);
}
}
/*打印结果: ABCDEFG*/
因为字符串一旦被初始化,就不可以被改变,以上代码中,subString(),concat()方法,只能改变返回值,并不能改变字符串原有的值。
2,字符串相加的结果
public class Demo{
public static void main(String[] args) {
String s1="abc";
String s2="def";
String s3=s1+s2;//这一步相当于StringBuilder sb=new StringBuiler();sb.append(s1); sb.append(s2);s3=sb.toString();
String s4="abcdef";//字符串存储在字符串常量池
System.out.println(s3.equals(s4));//内容比较是相等的
System.out.println(s3==s4);//因为地址不同,所以不等。
}
}
/*打印结果:
true
false
*/
3,字符串相加
public class Demo{
public static void main(String[] args) {
String s1="abc"+"def";//这一句话在编译时,编译器把+,当作连接符处理。相当于:s1="abcdef";
String s2="abcdef";//字符串存储在字符串常量池
System.out.println(s1.equals(s2));//内容比较是相等的
System.out.println(s1==s2);//因为指向同向的字符串,引用地址也是相等的。
}
}
/*打印结果:
true
true
*/
---------------------- ASP.Net+Android+IOS开发、 .Net培训、期待与您交流! ----------------------