字符串详解 常量池 字符串常量 常量

字符串详解

2018年02月25日 23:15:11 zhuwei1035838807 阅读数:38

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhuwei1035838807/article/details/79335453

一.字符串入门

1.字符串创建对象的方式:

(1) String str = "hello";  (在C语言中是没有字符串类型String,只有字符类型char,从而也就没有字符串类型的变量。一直以来                                    对这个问题都不是很清楚:只是知道C语言里有<string.h>这个头文件,所以就想当然的认为C语言里有                                    string这个 类型,可是通过下面这种形式来声明(定义)string的变量 string aString; 后来编程时发现通不                                    过编译,又查资料才知道原来C语言里压根就没有string这个类型,所以字符串都是通过char数组来存储                                 的, 而<string.h>这个头文件里声明的函数原型也全是针对char数组的种种操作。直到C++中才出现了                                       string这个类(注意是类, 不是类型)。)

这种方式创建字符串str2(若str2为新创建的字符串变量)的时候,Jvm(是指Java虚拟机)首先会检查字符串常量池中是否存在该字符串的对象,如果已经存在(若str1是已经在字符串常量池中创建了的字符串),那么就不会在字符串常量池中再创建了,直接返回该字符串在字符串常量池中的内存地址;如果该字符串在字符串常量池中并不存在,那么就会在字符串常量池中先创建该字符串的对象,然后再返回常量池中的内存地址所以str2=str1(地址相等,因为都是使用的是常量池某一内存的地址),这样同一个字符串"abc"有两个名字(这两个变量名是定义在栈去还是常量池区?:确认这两个变量str1str2在内存上),一个地址(常量池内存中的地址)

(2) new String("hello");

这种方式创建字符串对象的时候,Jvm首先会检查字符串常量池中是否存在“hello”的字符串,如果已经存在,则不会在字符串常量池中创建了,(直接返回该字符串在常量池中的内存地址??);如果还没有存在(即还没有创建),那么就会在字符串常量池中创建“hello”字符串对象然后还会去堆内存中再创建一份字符串的对象,把字符串常量池中的"hello字符串内容拷贝到堆内存中的字符串对象,然后返回堆内存中字符串对象的内存地址(堆内存地址这样刚刚创建的一个字符串"abc"就有两个名字,一个是常量区的,同时常量区也对应一个地址str3;一个是堆内存区的。因为堆内存区的是拷贝的,所以它会在堆区有一个地址str4,这两个地址不相同(str3不等于str4)。(这两个变量名是定义在栈去还是常量池区?:确认这两个变量str3 str4还是在内存上)

2.实例一

(1) 实例:

 
  1. public class Demo1 {

  2. public static void main(String[] args) {

  3. String str1 = "hello";//第一种创建字符串对象的方式

  4. String str2 = "hello";//第一种创建字符串对象的方式

  5. String str3 = new String("hello");//第二种创建字符串对象的方式

  6. String str4 = new String("hello");//第二种创建字符串对象的方式

  7. System.out.println("str1==str2?"+(str1==str2)); // true

  8. System.out.println("str2==str3?"+(str2==str3)); //false

  9. System.out.println("str3==str4?"+(str3==str4)); // false

  10. System.out.println("str3.equals(str4)?"+(str3.equals(str4))); //true

  11. }

  12. }

(2) 运行结果:

(3) 分析:

①首先会在栈内存中声明一个变量str1,然后用双引号引起创建字符串的对象,这时候Jvm就会检查字符串常量池中是否有hello,没有的话就会在字符串常量池中先创建这个对象,然后把这个对象的内存地址返回给str1,假设它的内存地址是0x97,这时候返回给str1的就是0x97,这时候str1是指向了内存地址为0x97所存储的字符串对象。

②然后又声明了一个变量str2,用双引号引起创建字符串的对象,这时候Jvm就会检查字符串常量池中是否有hello,发现字符串常量池中已经有了hello,那么就不会在字符串常量池中再创建了。直接把字符串常量池中hello的内存地址返回给这个变量就可以,也就是说str2记录的内存地址也是0x97.所以现在str1和str2指向的是同一个对象,所以运行结果为true。

③首先在栈内存中声明一个变量str3,当new String的时候,里面有一个双引号引起来的字符串,有双引号引起来的都会先到字符串常量池中先检查,Jvm在字符串常量池中检查的时候发现已经存在hello,就不会在字符串常量池中再创建了(如果没有这个字符串常量,那就在常量池中创建一个字符串对象,同时有一个地址与该对象相对应。),接着有个new关键字,凡是遇到new关键字,Jvm都会在堆内存中开辟一块新的内存空间(言外之意就是:new String的情况就是同时完成两个任务:一个是String:在栈区创建一个字符串对象(当然首先在常量池中创建字符串常量对象),一个是马上在堆区再创建一个字符串对象,此时堆内存也有一个与该对象对应的地址,堆内存上创建的字符串对象的内容是从常量池中拷贝过来的),这时候会在堆内存中创建一个堆内存的对象,接着会把字符串常量池中的hello的内容拷贝到堆内存创建的对象中去,接着会把堆内存的内存地址返回给str3,比如说它的内存地址是0x78,str3记录的则是0x78的内存地址,它指向的是堆内存中创建的对象的内存地址。

 

④在栈内存中声明一个变量str4,字符串常量池中有hello,那么就不会再创建,会到堆内存中创建一个字符串对象,把字符串常量池中的内容拷贝到堆内存中创建的对象中,比如说它的内存地址是0x76,这时候栈内存中str4记录的就是0x76内存地址所存储的对象。

(4) 疑问:str3和str4的内存地址并不一样,为什么运行结果返回的是true?

虽然equals方法默认情况下(注意是默认)比较的是两个对象的内存地址,而现在用到的是字符串的对象,那么我们就不允许字符串的类对equals方法进行重写吗?字符串也可以重写equals方法,重写后就可以不遵循默认的情况,因为看的是String中有没有重写equals方法,所以应该查看String的源代码,查看String的源代码后我们发现,重写后的equals方法比较的是两个字符串对应的字符是否一致。

3.为什么比较字符串的时候建议使用equals而不是==号?

因为==号比较的是内存地址,但是我们在现实开发中一般都是比较内容是否一致,所以就不建议使用==号,如果使用==号,str2和str3就会是false,使用equals,只要两个字符串的内容一致那么返回的结果都是一致的。

注意:"=="用于比较 引用数据类型数据的时候比较的是两个对象的内存地址,equals方法默认情况下比较的也是两个对象的内存地址。

4. new String("abc")创建了几个对象?

创建了两个对象,一个对象是位于字符串常量池中,一个对象是位于堆内存中。

5.实例二

(1) 实例:

 
  1. public class Demo2 {

  2. public static void main(String[] args) {

  3. test(null);

  4. }

  5. public static void test(String str){

  6. if(str.equals("中国"))

  7. {

  8. System.out.println("回答正确");

  9. }else{

  10. System.out.println("回答错误");

  11. }

  12. }

  13. }

  14.  
  15.  

(2) 运行结果:

(3) 分析:

 

首先str.equals("中国")运行后就会报空指针异常,如何避免这种错误?

那么就需要使用"中国".equals(str),这也是最简便的一种方式,调换位置后,"中国"是个常量,也就是这个常量在调用equals方法,这样就变成了常量是这个方法的调用者,变量作为参数这样就可以避免永远都不会出现空指针异常。因为如果函数的调用者是一个变量,这个变量有可能指向一个空的对象;如果函数的调用者是一个常量,常量不可能为空,永远都不可能为空也就不会出现空指针异常。这是一个编程习惯,使用equals方法时,我们一般都会让常量作为这个方法的调用者,这样就可以避免空指针异常的出现。

(4) 修改后的实例:

 
  1. public class Demo3 {

  2. public static void main(String[] args) {

  3. test(null);

  4. }

  5. public static void test(String str){

  6. if("中国".equals("str"))

  7. {

  8. System.out.println("回答正确");

  9. }else{

  10. System.out.println("回答错误");

  11. }

  12. }

  13. }

(5) 运行结果:

二.String类的构造方法

注意:使用字节数组或者字符数组都可以构建一个字符串对象。

1.String();

(1) 该方法用于创建一个空内容的字符串对象。

(2) 实例:

 
  1. //String类的无参的构造方法。

  2. public class Demo4 {

  3. public static void main(String[] args) {

  4. String str = new String();//调用String类的无参的构造方法,相当于String str = " ";

  5. System.out.println("字符串的内容是:"+str);

  6. }

  7. }

  8.  
  9.  

(3) 运行结果:

2.String(byte[] bytes) ;

(1) 该方法用于使用一个字节数组构建一个字符串对象;

(2) 实例:

 
  1. //String(byte[] bytes) 使用一个字节数组构建一个字符串对象

  2. public class Demo5 {

  3. public static void main(String[] args) {

  4. byte[] buf = {97,98,99};//这些字节数组里存储的都是那些字符对应的码值

  5. String str = new String(buf); //使用一个字节数组构建一个字符串对象

  6. System.out.println("字符串的内容:"+str);

  7. }

  8. }

  9.  

(3) 运行结果:

3.String(byte[] bytes, int offset, int length) 

(1) 参数详解:  

bytes:要解码的数组(解码就是把数字转换成数字代表的字符)

offset:指定从数组中那个索引值开始解码。也就是说从字节数组中的哪一位开始查找对应的字符。
length:要解码多少个元素。也就是要查找多少个字符。

(2) 实例:

 
  1. public class Demo6 {

  2. public static void main(String[] args) {

  3. byte[] buf = {97,98,99};

  4. String str = new String(buf,1,2);//使用一个字节数组构建一个字符串对象,指定开始解码的索引值和解码的个数

  5. System.out.println("字符串的内容:"+str);

  6. }

  7. }

  8.  

(3) 运行结果:

4.String(char[] value);  

(1) 使用一个字符数组构建一个字符串。

(2) 实例:

 
  1. //String(char[] value) 使用一个字符数组构建一个字符串。

  2. public class Demo7 {

  3. public static void main(String[] args) {

  4. char[] arr = {'马','上','毕','业','了'};

  5. String str = new String(arr); //使用字符数组构建一个字符串

  6. System.out.println("字符串的内容:"+str);

  7. }

  8. }

  9.  
  10.  

(3) 运行结果:

5.String(char[] value, int offset, int count);  

(1) 使用一个字符数组构建一个字符串, 指定开始的索引值,与使用字符个数。

(2) 实例:

 
  1. public class Demo8 {

  2. public static void main(String[] args) {

  3. char[] arr = {'马','上','毕','业','了'};

  4. String str = new String(arr,2,2);

  5. System.out.println("字符串的内容:"+str);

  6. }

  7. }

  8.  

(3) 运行结果:

6.String(int[] codePoints,int offset,int count);

(1) 实例:

 
  1. public class Demo9 {

  2. public static void main(String[] args) {

  3. int[] buf = {65,66,67};

  4. String str = new String(buf,0,3);

  5. System.out.println("字符串的内容:"+str);

  6. }

  7. }

  8.  

(2) 运行结果:

三.String类的普通常用方法

1.获取的方法

(1) 方法:

①int length():该方法用于获取字符串的长度。

②char charAt(int index):传入一个索引值,根据索引值获取特定位置的字符 (注意角标越界)。

③int indexOf(String str):查找子串第一次出现的索引值,如果子串没有出现在字符串中,那么则返回-1表示。

④int lastIndexOf(String str):查找子串最后一次出现的索引值 , 如果子串没有出现在字符串中,那么则返回-1表示。

(2) 实例:

 
  1. public class Demo3 {

  2. public static void main(String[] args) {

  3. String str = "abc你好ab你好";

  4. System.out.println("字符串的字符个数:" + str.length());

  5. System.out.println("根据索引值获取对应的字符:"+ str.charAt(3));

  6. System.out.println("查找子串第一次出现的索引值:" + str.indexOf("你好"));

  7. System.out.println("查找子串最后一次出现的索引值:" + str.lastIndexOf("你好"));

  8. }

  9. }

  10.  

(3) 运行结果:

 

2.判断的方法

(1) 方法:

①boolean endsWith(String str):判断是否以指定字符串结束。
②boolean isEmpty():判断长度是否为0,也就是判断字符串是否为空内容。
③boolean contains(CharSequences):判断是否包含指定序列,该方法可以应用于搜索。
④boolean equals(Object anObject):判断是否相等,判断两个字符串的内容是否一致。是区分大小写的。

⑤boolean equalsIgnoreCase(String anotherString) 忽略大小写是否相等,验证码都是忽略大小写的。

(2) 实例:

 
  1. public class Demo11 {

  2. public static void main(String[] args) {

  3. String str = "Demo.java";

  4. System.out.println("是否以指定 的字符串结束:"+ str.endsWith("java"));

  5. System.out.println("是否以指定 的字符串结束:"+ str.endsWith("va"));

  6. System.out.println("是否以指定 的字符串结束:"+ str.endsWith("ja"));

  7.  
  8. System.out.println("判断字符串是否为空内容:"+str.isEmpty());

  9. System.out.println("判断字符串是否包含指定的内容:"+ str.contains("Demo"));

  10. System.out.println("判断两个 字符串的内容是否一致:"+ "DEMO.JAVA".equals(str));

  11. System.out.println("判断两个字符串的内容是否一致(忽略大小写比较):"+ "DEMO.JAVA".equalsIgnoreCase(str));

  12. }

  13. }

  14.  
  15.  

(3) 运行结果:

3.转换的方法

注意:字节数组与字符数组、字符串他们三者之间是可以互相转换的。

(1) 方法:

①char[] toCharArray() :将字符串转换为字符数组。

②byte[] getBytes():将字符串转换为字节数组。

(2) 实例:

 
  1. import java.util.Arrays;

  2. public class Demo12 {

  3. public static void main(String[] args) {

  4. String str = "Demo.java";

  5. char[] buf = str.toCharArray(); //把字符串转换字符数组

  6. System.out.println("字符数组:"+ Arrays.toString(buf));

  7. byte[] buf2 = str.getBytes(); //把字符串转字节数组

  8. System.out.println("字节数组:"+ Arrays.toString(buf2));

  9. }

  10. }

  11.  

(3) 运行结果:

4.其他的方法

注意:CharSequence是一个接口,而String类是它的实现类。

(1) 方法:

①String replace(String oldChar, String newChar):替换。

②String[] split(String regex):切割。
③String substring(int beginIndex):指定开始的索引值截取子串。
④String substring(int beginIndex, int endIndex):指定开始与结束的索引值截取子串。
⑤String toUpperCase():转大写。
⑥String toLowerCase():转小写。

⑦String trim():去除字符串首尾的空格。

(2) 实例:

 
  1. public class Demo5 {

  2. public static void main(String[] args) {

  3. String str = "我们不学习";

  4. System.out.println("指定新内容替换旧 的内容:"+ str.replace("不", "要好好"));

  5. str = "我们要-好-好-学-习";//切成5份

  6. String[] arr = str.split("-"); //根据指定的字符进行切割 。

  7. System.out.println("字符串数组的内容:"+ Arrays.toString(arr));

  8. str = "马上要毕业了";

  9. System.out.println("指定开始的索引值截取子串:"+ str.substring(2));

  10. System.out.println("指定开始与结束的索引值截取子串:"+ str.substring(2,6)); //方法重载,包头不包尾 注意:截取的内容是包括开始的索引值,不包括结束的索引值, 截取的位置是结束的索引值-1.

  11. //注意,凡是Java方法中出现开始和结束的索引值,都是遵循包头不包尾

  12. str = "abC中国";

  13. System.out.println("转大写:" + str.toUpperCase());

  14. str = "AbdfSDD";

  15. System.out.println("转小写:"+ str.toLowerCase());

  16. str = " 我们要 努力学习 ";

  17. System.out.println("去除字符串首尾的空格:"+ str.trim());

  18. }

  19. }

  20.  
  21.  

(3) 运行结果:

四.字符串实例:

1.实例一

(1) 需求:自己实现trim的方法。

(2) 分析:只要我们能确定开始StartIndex和结束endIndex这两个位置的索引值,那么这个题目我们就能做出来。最关键的是这两个索引值应该如何确定?把这两个变量定义成这个字符串开始与结束的位置,首先用startIndex确定是否是空字符,是的话就前进一步,结束的索引值也要判断是否是空字符。是的话就后退一步。

(3) 实例:

 
  1. public class Demo1 {

  2. public static void main(String[] args) {

  3. String str =" 我们 快要毕业了 ";

  4. System.out.println(myTrim(str));

  5. }

  6. public static String myTrim(String str){

  7. //先转换成字符 数组

  8. char[] arr = str.toCharArray();

  9. //定义两个 变量记录开始与结束 的索引值

  10. int startIndex = 0 ;

  11. int endIndex = arr.length -1;

  12. //确定开始 的索引值

  13. while(true){

  14. if(arr[startIndex]==' '){

  15. startIndex++;

  16. }else{

  17. break;

  18. }

  19. }

  20. //确定结束 的索引值:

  21. while(true){

  22. if(arr[endIndex]==' '){

  23. endIndex--;

  24. }else{

  25. break;

  26. }

  27. }

  28. //截取子串返回

  29. return str.substring(startIndex,endIndex+1);

  30. }

  31. }

  32.  

(4) 运行结果:

2.实例二

(1) 需求:

获取上传文件名  "D:\\20180225\\day01\\Demo1.java"。从字符串中获取文件名为Demo1.java。

(2) 分析:

可以用切割的方法,按照"\\"来进行切割,把它分割成好几部分,返回一个字符串的数组,只获取字符串数组的最后一个就可以了;也可以用截取的方法,只要能确定D的索引值就可以了。那么如何确定D的索引值?也就是最后"\\"的索引值+1就是D的索引值。

(3) 实例:

 
  1. public class Demo2 {

  2. public static void main(String[] args) {

  3. String str = "D:\\20180225\\day01\\Demo1.java";

  4. getFileName(str);

  5. }

  6. public static void getFileName(String path){

  7. int index = path.lastIndexOf("\\");//转义

  8. String fileName = path.substring(index+1);

  9. System.out.println("文件名:"+ fileName);

  10. }

  11. }

  12.  
  13.  

(4) 运行结果:

3.实例三

(1) 需求:

将字符串对象中存储的字符反序。例如:新中国好 -----> 好国中新。

(2) 分析:

只需要把它转换成一个字符数组,转成字符数组后就可以定义两个索引值,一个是开始的索引值startIndex,另一个是结束的索引值endIndex,这两个交换后,startIndex向前++,endIndex向后--,再继续进行交换,(要定义两个变量记录要交换位置的索引值,只要startIndex<endIndex那么就进行交换),当这个字符数组被反转后,我们只需要再使用这个字符数组构建一个字符串即可。

(3) 实例:

 
  1. public class Demo3 {

  2. public static void main(String[] args) {

  3. String str = "新中国好";

  4. System.out.println("翻转后的字符串:"+ reverse(str));

  5. }

  6. public static String reverse(String str){

  7. char[] arr = str.toCharArray();

  8. for(int startIndex = 0 , endIndex=arr.length-1 ; startIndex<endIndex; startIndex++,endIndex--){

  9. char temp = arr[startIndex];

  10. arr[startIndex] = arr[endIndex];

  11. arr[endIndex] = temp;

  12. }

  13. //使用字符数组构建一个字符串。

  14. return new String(arr);

  15. }

  16. }

  17.  
  18.  

(4) 运行结果

4.实例四

(1) 需求:

求一个子串在整串中出现的次数 。

(2) 分析:

先定义一个变量记录出现的次数,count = 0;接着定义一个变量用于记录开始寻找的索引值的位置,int fromIndex = 0;首先从索引值为0的地方开始找,找到第一个Java后,count++,然后继续开始向后寻找,第一次找到Java的索引值是3,第二次是从java后的a开始继续往后找,而这个a的索引值是7,那么第二次的fromIndex应该怎么计算出来?首先确定第一次java的索引值为3,接着java的长度是4,所以第二次从a的索引值7开始找。

(3) 实例:

 
  1. public class Demo4 {

  2. public static void main(String[] args) {

  3. String str = "abcjavaabcjavaphpjava"; //统计java在这个字符串中出现的次数

  4. getCount(str, "java");

  5. }

  6. //统计子串出现 的次数

  7. public static void getCount(String str,String target){

  8. int count = 0 ; //用于记录出现的次数

  9. int fromIndex = 0; // 记录从那个索引值开始寻找目标子串

  10. while((fromIndex = str.indexOf(target, fromIndex))!=-1){

  11. //如果indexof方法返回 的不是-1,那么就是已经找到了目标 元素。

  12. //如果这个方法返回的是-1意味着再往后找就没有了,所以循环的结束条件是只要不等于-1就继续往后找。

  13. //indexOf会返回一个索引值,找到之后会有一个返回值,比如返回3,那么就应该用fromIndex来记录它。

  14. //因为下次开始寻找的位置是

  15. count++;

  16. fromIndex = fromIndex+target.length();

  17. }

  18. System.out.println("出现的次数:"+ count);

  19. }

  20. }

  21.  
  22.  

(4)  运行结果:

五.StringBuffer类

1.前言

(1) 字符串的特点:字符串是常量,它们的值在创建之后不能更改。

(2) 字符串的内容一旦发生了变化,那么马上会创建一个新的对象。

(3) 实例:

 
  1. public class Demo1 {

  2. public static void main(String[] args) {

  3. String str1 = "hello";

  4. String str2 = str1+" world";

  5. System.out.println("str1与str2是同一个 对象吗?"+(str1==str2));

  6. }

  7. }

运行结果如下图所示:

2.StringBuffer类: 

(1) 字符串的内容不适宜频繁修改,因为一旦修改马上就会创建一个新的对象。如果不断频繁修改,在内存中就会有很多的字符串对象存在。如果需要频繁修改字符串的内容,建议使用字符串缓冲类(StringBuffer)。

(2) StringBuffer 是字符串的缓冲区,其实就是一个存储字符的容器,用它对字符串进行增删查改会非常方便。

 

(3) 疑问:使用Stringbuffer无参的构造函数创建 一个对象时,默认的初始容量是多少?如果长度不够使用了,自动增长多少倍?

通过查看源代码我们发现,StringBuffer 底层是依赖了一个字符数组才能存储字符数据的,该字符串数组默认 的初始容量是16, 如果字符数组的长度不够使用时,自动增长1倍,也就是是原来的2倍。

(4) 实例:

 
  1. public class Demo2 {

  2. public static void main(String[] args) {

  3. //先使用StringBuffer无参的构造函数创建一个字符串缓冲类。

  4. StringBuffer sb = new StringBuffer();

  5. sb.append("java");

  6. sb.append("java");

  7. sb.append("java");

  8. sb.append("java");

  9. sb.append("java");

  10. System.out.println(sb);//其初始容量为16个字符,但是为什么可以输出20个字符。

  11. }

  12. }

运行结果如下图所示:

3.StringBuffer类具备的方法:

(1) 增加的方法:

①append(boolean b) :有很多重载的方法,可以添加任意类型的数据到容器中。

 
  1. package stringbuffer;

  2. public class append {

  3. public static void main(String[] args) {

  4. StringBuffer sb = new StringBuffer();

  5. //添加的方法

  6. sb.append("abc");

  7. sb.append(true);//把true变成字符串输出

  8. sb.append(3.14f);

  9. System.out.println("字符串缓冲类的内容:"+sb);

  10. }

  11. }

运行结果如下图所示:

②insert(int offset, boolean b):指定插入的索引值,插入对应的内容。

 
  1. public class insert {

  2. public static void main(String[] args) {

  3. StringBuffer sb = new StringBuffer();

  4. //插入的方法

  5. sb.append("abc");

  6. sb.insert(2,"小明");//在b和c之间插入小明,因为b和c之间的索引值是2.

  7. System.out.println("字符串缓冲类的内容:"+sb);

  8. }

  9. }

  10.  

运行结果如下图所示:

(2) 删除的方法

①delete(int start, int end):根据指定的开始与结束的索引值删除对应的内容。

 
  1. public class delete {

  2. public static void main(String[] args) {

  3. StringBuffer sb = new StringBuffer();

  4. sb.append("abc");

  5. sb.insert(2,"小明");

  6. System.out.println("执行删除操作前:"+sb);

  7. //删除的方法

  8. sb.delete(2, 4);//删除小明,删除的时候也是包头不包尾的。

  9. System.out.println("执行删除操作后:"+sb);

  10. }

  11. }

运行结果如下图所示:

②deleteCharAt(int index):根据指定 的索引值删除一个字符。

 
  1. public class deleteCharAt {

  2. public static void main(String[] args) {

  3. StringBuffer sb = new StringBuffer();

  4. sb.append("abc");

  5. sb.insert(2,"小明");

  6. System.out.println("执行删除操作前:"+sb);

  7. //删除

  8. sb.deleteCharAt(3);//删除"明"

  9. System.out.println("执行删除操作后:"+sb);

  10. }

  11. }

运行结果如下图所示:

(3) 修改的方法

①replace(int start, int end, String str):根据指定 的开始与结束索引值替代成指定的内容。

 
  1. public class replace {

  2. public static void main(String[] args) {

  3. StringBuffer sb = new StringBuffer();

  4. sb.append("abc");

  5. sb.insert(2,"小明");

  6. System.out.println("执行替换操作前:"+sb);

  7. //替换

  8. sb.replace(2,4,"张三");//把小明替换成张三

  9. System.out.println("执行替换操作后:"+sb);

  10. }

  11. }

运行结果如下图所示:

②reverse():反转字符串缓冲类的内容。abc--->cba

 
  1. public class reverse {

  2. public static void main(String[] args) {

  3. StringBuffer sb = new StringBuffer();

  4. sb.append("abc");

  5. sb.insert(2,"小明");

  6. System.out.println("执行反转操作前:"+sb);

  7. //反转字符串的内容

  8. sb.reverse();

  9. System.out.println("执行反转操作后:"+sb);

  10. }

  11. }

运行结果如下图所示:

③setCharAt(int index, char ch):把指定索引值的字符替换成指定的字符。 

 
  1. public class setCharAt {

  2. public static void main(String[] args) {

  3. StringBuffer sb = new StringBuffer();

  4. sb.append("abc");

  5. sb.insert(2,"小明");

  6. System.out.println("执行替换操作前:"+sb);

  7. //替换单个字符

  8. sb.setCharAt(3, '红');//把'明'替换成'红'

  9. System.out.println("执行替换操作后:"+sb);

  10. }

  11. }

运行结果如下图所示:

④substring(int start, int end):根据指定的索引值截取子串。

 
  1. public class substring {

  2. public static void main(String[] args) {

  3. StringBuffer sb = new StringBuffer();

  4. sb.append("abc");

  5. sb.insert(2,"小明");

  6. //截取小明

  7. String subString = sb.substring(2, 4);//返回类型是String类型

  8. System.out.println("子串的内容:"+subString);

  9. }

  10. }

运行结果如下图所示:

⑤ensureCapacity(int minimumCapacity):指定StringBuffer内部的字符数组长度的。基本很少用到。

如果想指定字符数组的初始容量可以使用带参的构造方法来指定。

 
  1. public class ensureCapacity {

  2. public static void main(String[] args) {

  3. StringBuffer sb = new StringBuffer();

  4. sb.append("abc");

  5. sb.insert(2,"小明");

  6. sb.ensureCapacity(20);//指定字符数组的长度为20,默认是16

  7. }

  8. }

(4) 查看的方法

①indexOf(String str, int fromIndex):查找指定的字符串第一次出现的索引值,并且指定开始查找的位置。

 
  1. public class indexOf {

  2. public static void main(String[] args) {

  3. StringBuffer sb = new StringBuffer();

  4. sb.append("abcjavaabc");

  5. int index = sb.indexOf("java", 0);//从索引值为0的位置开始找

  6. System.out.println("返回的索引值为:"+index);

  7. }

  8. }

运行结果如下图所示:

②capacity():查看当前字符数组的长度。 

 
  1. public class capacity {

  2. public static void main(String[] args) {

  3. StringBuffer sb = new StringBuffer();

  4. sb.append("abcjavaabc");

  5. //查看当前字符数组的长度

  6. System.out.println("当前字符数组的长度是:"+sb.capacity());//16

  7. sb.append("javajava");//此时存储了18个字符,那么这时候当前字符数组的长度又是多少?

  8. System.out.println("当前字符数组的长度是:"+sb.capacity());//34,因为字符串的长度会增长一倍+2

  9. }

  10. }

运行结果如下图所示:

③length():查看存储字符的个数。

 
  1. public class length {

  2. public static void main(String[] args) {

  3. StringBuffer sb = new StringBuffer();

  4. sb.append("abcjavaabc");

  5. sb.append("javajava");

  6. System.out.println("查看当前字符数组存储字符的个数:"+sb.length());

  7. }

  8. }

运行结果如下图所示:

④charAt(int index):根据指定的索引值查找字符

 
  1. public class charAt {

  2. public static void main(String[] args) {

  3. StringBuffer sb = new StringBuffer();

  4. sb.append("abcjavaabc");

  5. sb.append("javajava");

  6. System.out.println("根据指定的索引值查找字符:"+sb.charAt(2));

  7. }

  8. }

运行结果如下图所示:

⑤toString():把字符串缓冲类的内容转成字符串返回。

现在stringBuffer里存储了很多的字符数据,假设有一个test方法,这个方法是要接收一个字符串的,而字符的内容是存储在StringBuffer里的。而现在调用这个test方法应该如何调用呢?首先肯定不能把sb传进去,因为类型不一样,如何把这个容器中存储的字符转换成字符串呢?可以用sb.toString()方法,这样就会把里面存储的内容,以字符串的形式返回。

 
  1. public class toString {

  2. public static void main(String[] args) {

  3. StringBuffer sb = new StringBuffer();

  4. sb.append("abcjavaabc");

  5. sb.append("javajava");

  6. String content = sb.toString();

  7. test(content);

  8. }

  9. public static void test(String str){

  10. System.out.println("字符串缓冲类的内容是:"+str);

  11. }

  12. }

运行结果如下图所示:

六.StringBuilder类

1.StringBuffer 与 StringBuilder的相同处与不同处:

(1) 相同点:
①两个类都是字符串缓冲类。
②两个类的方法都是一致的。(只要是StringBuffer有的方法,StringBuilder一样有)
(2) 不同点:
①StringBuffer是线程安全的,操作效率低 ,StringBuilder是线程非安全的,操作效率高。
(所谓的安全是指在一个时间段里只会允许一个线程来操作这份代码,而线程不安全是指在一个时间段里一份代码可以由多个线程来执行)
②StringBuffer是jdk1.0出现 的,StringBuilder 是jdk1.5的时候出现的。

2.推荐使用:StringBuilder,因为操作效率高。

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值