38、常用类之String类

╰半橙微兮° 2024-03-31 09:03 162阅读 0赞

1、基本介绍:

48336dad93e44fee94f5ee9af7b2f300.png

·String s5=new String(byte[] b);

22d1480d886241dcaed191f9fa626e10.png

(5)String实现了Serializable,说明String可以串行化,即可以网络传输

String实现了Comparable,说明String对象可以比较

(6)String和所有包装类都是final,不可被继承

String是一个final类,代表不可变的字符序列,字符串是不可变的,一个字符串对象一旦被分配,其内容是不可变的

(7)String有属性private final char value[]; 用于存放字符串内容(注意value是final类型,指向的地址不可修改(里面单个字符内容可以修改),因为基本类型的final是值不可修改,但char是引用类型,所以是地址不可修改)

  1. package String_;
  2. public class String01 {
  3. public static void main(String[] args) {
  4. String name="jack";
  5. name="tom";
  6. final char[] value={'a','b','c'};
  7. char[] v2={'t','o','m'};
  8. value[0]='H';//修改value里的内容
  9. //value=v2;//报错,因为value不能指向新的地址v2
  10. System.out.println(value);//输出:Hbc
  11. }
  12. }

2、创建String对象的两种方式:

方式一:直接赋值String s=”hspedu”;

先从常量池查看是否有”hspedu”数据空间,如果有,直接指向;如果没有则重新创建,然后指向,s最终指向的是常量池的空间地址

方式二:调用构造器String s=new String(“hspedu”);

先在堆中创建空间,里面维护了value属性,指向常量池的”hspedu”空间,如果常量池没有”hspedu”,重新创建,如果有,直接通过value指向,最终指向的是堆中的空间地址

8d139bf93eda49088a0a82dfce05782c.png

  1. String a="abc";
  2. String b="abc";
  3. System.out.println(a.equals(b));//T,比较内容
  4. //源码:public boolean equals(Object anObject) {
  5. // if (this == anObject) {
  6. // return true;
  7. // }
  8. // return (anObject instanceof String aString)
  9. // && (!COMPACT_STRINGS || this.coder == aString.coder)
  10. // && StringLatin1.equals(value, aString.value);
  11. // }
  12. System.out.println(a==b);
  13. //T,比较地址,a在常量池没有找到"abc",所以创了一个"abc",
  14. // b在常量池里找到了a的"abc",所以指向了a的"abc",不用自己创了,
  15. // 所以它们指向的是同一个地址
  16. String a="abc";
  17. String b=new String("abc");
  18. System.out.println(a==b);//F,a指向的是常量池里的对象,
  19. // b指向的是堆中的对象(该对象又指向常量池里a的"abc")
  20. System.out.println(a==b.intern());//T
  21. System.out.println(b==b.intern());//T
  22. //b.intern()指向的是常量池里a的对象,

补:b.intern()方法最终返回的是常量池的地址(对象)

当调用intern方法时,如果池已经包含一个等于此String对象的字符串(用equals(Object)方法确定),则返回池中的字符串,否则将此String对象添加到池中,并返回此String对象的引用

  1. Person p1=new Person();
  2. p1.name="hsp";
  3. Person p2=new Person();
  4. p2.name="hsp";
  5. System.out.println(p1.name==p2.name);
  6. //T,因为比较的是p.name的地址不是p的地址,
  7. // 而p1.name和p2.name都指向常量池里的同一个地址

0049e004d82346fbb8b0f084b6d254ef.png

  1. String s="abc";
  2. s="hsp";
  3. //创建了两个对象
  4. String a="hello"+"abc";
  5. //创建了一个对象,
  6. //因为编译器会优化,判断创建的常量池对象,是否有引用指向,
  7. //即等价于String a="helloabc"

bceac9c84b754a2293165c437cce576f.png(大家做题做着做疯魔了,像赌徒一样,好搞笑啊!)

843f4a30c1d046a4bd7195961829c004.png

  1. String a="hello";
  2. String b="abc";
  3. String c=a+b;
  4. //底层分析:
  5. //1、先创建一个StringBuilder sb=StringBuilder();
  6. //2、执行sb.append("hello");
  7. //3、执行sb.append("abc");
  8. //4、String c=sb.toString;
  9. //sb是在堆中,并且append是在原来字符串的基础上追加的
  10. //最后其实是c指向堆中的对象(String) value[]——》池中"helloabc"
  11. String d="hello"+"abc";//d="helloabc"
  12. System.out.println(c==d);//false
  13. String e="helloabc"
  14. System.out.println(d==e);//true
  15. //常量相加,看的是池
  16. //变量相加,看的是堆

5f4417a270d0424f85da757c23649e4a.png

提示:尽量看源码学习

3、String类的常见方法:

String类是保存字符串常量的,每次更新都需要开辟空间,效率较低,因此java设计者还提供了StringBuilder和StringBu ffer来增强String的功能,并提高效率

5e2ea530c3c140159e56d2cf6ac543a7.png

7a735df0ea174e26a50cb24cf1e8a40b.png

  1. package String_;
  2. public class String01 {
  3. public static void main(String[] args) {
  4. String str1="hello";
  5. String str2="Hello";
  6. System.out.println(str1.equals(str2));//f, equals方法比较内容是否相同,区分大小写
  7. System.out.println(str1.equalsIgnoreCase(str2));//t, equalsIgnoreCase方法比较内容是否相同,不区分大小写
  8. System.out.println(str1.indexOf('e'));//输出:1,该字符第一次出现的地址
  9. System.out.println(str1.lastIndexOf('e'));//输出:1,该字符最后一次出现的地址
  10. System.out.println(str1.indexOf("el"));//输出:1,也可以是查找字符串第一个字母的地址
  11. System.out.println(str1.lastIndexOf("el"));//输出:1,查找字符串第一个字母最后一次出现的地址
  12. System.out.println(str1.substring(2));//输出:llo,截取索引2后面所有的字符
  13. System.out.println(str1.substring(0,2));//输出:he,截取索引为0到索引为2的所有字符
  14. }
  15. }

f914191e352b436bb028046074102f31.png

  1. package String_;
  2. public class String01 {
  3. public static void main(String[] args) {
  4. String s="hello";
  5. System.out.println(s.toUpperCase());//HELLO
  6. System.out.println(s.toLowerCase());//hello
  7. s=s.concat(" cheer ").concat(" up ").concat("TV");
  8. System.out.println(s);//hello cheer up TV
  9. System.out.println(s.replace("cheer","CHEER"));//hello CHEER up TV
  10. //注意:s.replace()方法执行后对原来的s没有任何影响
  11. String poem="锄禾日当午,汗滴禾下土,谁知盘中餐,粒粒皆辛苦";
  12. String[] split=poem.split(",");//以逗号为标准对poem进行分割,返回一个数组
  13. for(int i=0;i<split.length;i++){
  14. System.out.println(split[i]);
  15. }
  16. //输出:
  17. //锄禾日当午
  18. //汗滴禾下土
  19. //谁知盘中餐
  20. //粒粒皆辛苦
  21. //注意:在对字符串进行分割时,如果有特殊字符,需要加入转义字符\
  22. //如要以"\\"为标准分割,那应该是String[] split=poem.split("\\\\");
  23. //因为一个\对应一个\,两个\\加起来就一共是\\\\个了
  24. char[] ch=s.toCharArray();//把字符串转换成字符数组
  25. for(int i=0;i<ch.length;i++){
  26. System.out.println(ch[i]);
  27. }
  28. String s1="hello";
  29. String s2="hi";
  30. System.out.println(s1.compareTo(s2));//输出:-4 //因为e-i=-4
  31. //前>后,返回正数;后>前,返回负数,前=后,返回0
  32. String s3="hello";
  33. String s4="h";
  34. System.out.println(s3.compareTo(s4));//输出:4 //因为s3.length-s4.length=4
  35. //如果前面部分都相同,如hello和he比较,则是则返回的是字符串长度的差
  36. }
  37. }
  38. package String_;
  39. public class String01 {
  40. public static void main(String[] args) {
  41. String name="tom";
  42. int age=10;
  43. double score=98.8;
  44. char gender='男';
  45. String s="姓名:%s,年龄:%d,成绩:%.2f,性别:%c";//占位符,由后面的变量来替换
  46. System.out.println(String.format(s,name,age,score,gender));
  47. //输出:姓名:tom,年龄:10,成绩:98.80,性别:男
  48. }
  49. }

(1)StringBuffer类

1)java.lang.StringBuffer代表可变的字符序列,可以对字符串内容进行增删

2)很多方法与String相同,但StringBuffer是可变长度的

3)StringBuffer是一个容器

4)StringBuffer的直接父类是AbstractStringBuilder

5)StringBuffer实现了Serializable, 说明StringBuffer可以串行化,即可以网络传输

6)父类AbstractStringBuilder有属性char[] value,不是final,该value数组存放字符串内容,引出的是存放在堆中的(不再是常量池)

7)StringBuffer是一个final类,不能被继承

fcdd5bed295b40cab91c60126e4d234d.png

  1. StringBuffer stringBuffer=new StringBuffer();
  2. StringBuffer stringBuffer1=new StringBuffer(100);
  3. StringBuffer stringBuffer2=new StringBuffer("hello");

547d5305369c4c6ea7d116b899371652.png

  1. package String_;
  2. public class String01 {
  3. public static void main(String[] args) {
  4. StringBuffer s=new StringBuffer("hello");
  5. s.append(" h");
  6. s.append("i").append(" 100").append(true).append(10.5);//追加
  7. System.out.println(s);//hello hi 100true10.5
  8. s.delete(2,3);//删除
  9. System.out.println(s);//helo hi 100true10.5
  10. s.replace(0,5,"cheer");//替换
  11. System.out.println(s);//cheerhi 100true10.5
  12. s.indexOf("c");//查找
  13. System.out.println(s);//输出:0
  14. s.insert(5," up! ");//增加
  15. System.out.println(s);//输出:cheer up! hi 100true10.5
  16. }
  17. }

8)String 和StringBuffer的区别

1d8d43d80c284bc18da4d335a49200da.png

fe38d305b6cc40e88325b4fe1f822368.png

4、练习题

874f9945e83b431eb3ea1cb12f6a7630.png

//我的代码

  1. package String_;
  2. import java.util.Scanner;
  3. public class Homework01 {
  4. public static void main(String[] args) {
  5. System.out.println("请输入商品名称:");
  6. Scanner scanner1=new Scanner(System.in);
  7. System.out.println("请输入商品价格:");
  8. Scanner scanner=new Scanner(System.in);
  9. StringBuffer stringBuffer=new StringBuffer(String.valueOf(scanner));
  10. int j=stringBuffer.indexOf(".");
  11. for(int i=j;i>0;){
  12. stringBuffer.insert(i,",");
  13. i=i-3;
  14. }
  15. System.out.println("商品名称\t"+"商品价格");
  16. System.out.println(scanner1+"\t"+stringBuffer);
  17. }
  18. }

//老师的代码

  1. package String_;
  2. import java.util.Scanner;
  3. public class Homework01 {
  4. public static void main(String[] args) {
  5. String price="1234567.59";
  6. StringBuffer sb=new StringBuffer(price);
  7. for(int i=sb.lastIndexOf(".")-3;i>0;i-=3){
  8. sb=sb.insert(i,",");
  9. }
  10. System.out.println(sb);//1,234,567.59
  11. }
  12. }

(2)StringBuilder类

1)是一个可变的字符序列,此类提供一个与StringBuffer兼容的API,但不保证同步(StringBuilder不是线程安全),该类被设计用作StringBuffer的一个简易替换,用在字符串缓冲区被单个线程使用时,如果可能,建议优先采用该类,因为在大多数实现中,它比StringBuffer要快

2)在StringBuilder上的主要操作是append和insert方法,可重载这些方法,以接受任意类型的数据

43f55a48290c4017bafb4638c95239e0.png

3)StringBuilder和StringBuffer均代表可变的字符序列,方法是一样的,所以使用和StringBuffer一样

4)StringBuilder是final

5)继承了AbstractStringBuilder,属性char[] value,内容存到value,因此字符序列是在堆中

6)实现了Serializable接口,StringBuilder对象可以串行化,即可以网络传输,可以保存到文件。序列化(所谓序列化即可以保存类型和数据本身)

7)StringBuilder的方法,没有做互斥处理,即没有synchronized关键字,因此在单线程的情况下使用

923377f74e6f4d4484f95b8ecb6e621f.png

a12ea1e0f8804ad1bde08c659365936e.png

发表评论

表情:
评论列表 (有 0 条评论,162人围观)

还没有评论,来说两句吧...

相关阅读

    相关 String

    一、String类 String类在java.lang包中,java使用String类创建一个字符串变量,字符串变量属于对象。java把String类声明的final类,不