Java基础——String类、StringBuffer类、StringBuilder类

String类

  1. String对象用于保存字符串,也就是一组字符序列
  2. 字符串常量对象是用双引号括起的字符序列。例:"hello","3.1415926","年后"等。
  3. 字符串的字符使用Unicode字符编码,一个字符(不区分字母还是汉字)占两个字节。
  4. String类较常用的构造器:
    1. String s1=new String();
    2. String s2=new String(String original);
    3. String s3=new String(char[ ] a);
    4. String s4=new String(char[] a,int startIndex,int count)
  5. String 类实现了接口 Serializable  【String 可以串行化:可以在网络中传输 】,也实现 接口Comparable 【String 对象可以比较大小】
  6. String 是final类,不能被其他类继承。
  7. String 有属性 private final char value[];用于存放字符串内容。
  8. 一定注意:value 是一个fianl类型,不可修改(不是字符内容不可修改,是存放地址不可修改)

创建String对象的两种方式

  1.  方式一:直接赋值String s="nihao";
  2. 方式二:调用构造器String s=new String("nihao");

区别:

  1. 方式一:先从常量池查看是否有"nihao"的数据空间,如果有,直接指向;如果没有则重新创建,然后指向。s最终指向的是常量池的空间地址。
  2. 方式二:先在堆中创建空间,里面维护了value属性,指向常量池的"nihao"空间。如果常量池中没有"nihao",重新创建,如果有,直接通过value指向。最终指向的是堆中的空间地址。

字符串特性

  1. String是一个final类,代表不可变的字符序列

  2. 字符串是不变的。一个字符串对象一旦被分配,其内容是不可变的。

package com.study.srv.demo11;

/**
 * @author Wen先森
 * @version 1.0
 * @date 2022/3/10 10:12
 */
public class Demo05 {
    public static void main(String[] args) {
        String a="hello";
        String b="abc";
        String c=a+b;
        String d=a+"abc";
        //底层是StringBuilder sb=new StringBuilder(); sb.append(a);sb.append("abc"); sb是在堆中,并且append是在原来字符串的的基础上追加的。
        //重要规则,String e="hello"+"abc";常量相加,看的是常量池。String d=a+"abc";变量相加,是在堆中。
        String e="hello"+"abc";
        String f="helloabc";
        System.out.println(e==f);//说明 String e="hello"+"abc";会自动优化,等价于String f="helloabc";
        System.out.println(c);
        System.out.println(d);
        System.out.println(c==d);
        System.out.println(c==e);
        System.out.println(d==e);
        System.out.println(d==f);
    }
}

String d 创建过程如下:

 因此与String e="hello"+"abc";这种常量相加指向常量池的不同

String类的常见方法

方法名说明
equals区分大小写,判断内容是否相等
equalsgnoreCase忽略大小写的判断内容是否相等
length获取字符的个数,字符的长度
indexOf获取字符在字符串中第一次出现的索引,索引从0开始,如果找不到,返回-1
lastIndexOf获取字符在字符串中最后一次出现的索引,索引从0开始,如果找不到,返回-1
substring截取指定范围的子串
trim去前后空格
charAt获取某索引处的字符,注意不能使用Str[index]这种方式
toUpperCase

将小写字母转换为大写字母

toLowerCase将大写字母转换为小写字母
concat字符串拼接
replace替换字符串中的字符
spit分割字符串
compareTo比较两个字符串大小,如果前者大,则返回正数;后者大,则返回负数;如果相等,则返回0
toCharArray转换为字符数组
valueOf将其他类型转换为字符串
format格式化字符串

String.valueOf()方法

由基本数据型态转换成String:

  1. String.valueOf(boolean b) : 将 boolean 变量 b 转换成字符串 
  2. String.valueOf(char c) : 将 char 变量 c 转换成字符串 
  3. String.valueOf(char[] data) : 将 char 数组 data 转换成字符串 
  4. String.valueOf(char[] data, int offset, int count) : 将 char 数组 data 中 由 data[offset] 开始取 count 个元素 转换成字符串 
  5. String.valueOf(double d) : 将 double 变量 d 转换成字符串 
  6. String.valueOf(float f) : 将 float 变量 f 转换成字符串 
  7. String.valueOf(int i) : 将 int 变量 i 转换成字符串 
  8. String.valueOf(long l) : 将 long 变量 l 转换成字符串 
  9. String.valueOf(Object obj) : 将 obj 对象转换成 字符串, 等于 obj.toString() 

由 String 转换成 数字的基本数据型态 :

 要将 String 转换成基本数据型态转 ,大多需要使用基本数据型态的包装类别 。

  1. byte : Byte.parseByte(String s) : 将 s 转换成 byte类型。
  2. Byte.parseByte(String s, int radix) : 以 radix是进制数 将 s 转换为 byte ,比如说 Byte.parseByte("11", 16) 就代表是16进制的"11",也就是17。
  3. double : Double.parseDouble(String s) : 将 s 转换成 double 。
  4. float : Double.parseFloat(String s) : 将 s 转换成 float 。
  5. int : Integer.parseInt(String s) : 将 s 转换成 int 。
  6. long : Long.parseLong(String s)。

StringBuffer类

  • java.lang.StringBuffer代表可变的字符序列,可以对字符串内容进行增删。
  • 很多方法与Sting相同,但StringBuffer是可变长度。
  • StringBuffer是一个容器。

package com.study.srv.demo11;

/**
 * @author Wen先森
 * @version 1.0
 * @date 2022/3/11 11:52
 */
public class Demo09 {
    public static void main(String[] args) {
        //1.StringBuffer的直接父类就是 AbstractStringBuilder
        //2.它也实现了java.io.Serializable接口 即StringBuffer的对象可以串行化
        //3.在父类中 有属性char[] value;不是final类型,该value数组存放字符串内容
        //4.StringBuffer是一个final类不能被继承。
        StringBuffer stringBuffer = new StringBuffer();
    }
}

String  VS  StringBuffer

  1. String保存的是字符串常量,里面的值不能更改,每次String类的更新实际上就是更改地址,效率较低    //private final char value[];
  2. StringBuffer保存的是字符串变量,里面的值可以更改,每次StringBuffer的更新实际上可以更新内容,不用更新地址,效率较高//  char[] value;
StringBuffer stringBuffer =new StringBuffer();

默认创建一个大小为16的char[],用于存放字符内容。实际上真正存放在父类的value里。

  

 StringBuffer stringBuffer =new StringBuffe(100);

通过构造器指定char[]大小。

 StringBuffer stringBuffer = new StringBuffer("hello");

 StringBuffer转换

package com.study.srv.demo11;

/**
 * @author Wen先森
 * @version 1.0
 * @date 2022/3/11 16:01
 */
public class Demo10 {
    public static void main(String[] args) {
        //String 转换为StringBuffer
        String str="hello world";
        //方式一:使用构造器
        //注意:返回的是StringBuffer对象,对str本身没有影响。
        StringBuffer stringBuffer = new StringBuffer(str);

        //方式二:使用的是append方法
        StringBuffer stringBuffer1 = new StringBuffer();
        stringBuffer1 = stringBuffer1.append(str);

        //StringBuffer转为String
        StringBuffer stringBuffer2 = new StringBuffer("jack");
        //方式一:使用StringBuffer提供的toString方法
        String s=stringBuffer2.toString();
        System.out.println(s);

        //方式二:使用构造器搞定
        String s1 = new String(stringBuffer2);
        System.out.println(s1);

    }
}

 StringBuffer常用方法

方法名说明
append增加
delete(start,end)删除
replace(start,end,string)将start--end间的内容替换掉,不含end
reverse()字符串翻转
indexOf查找子串在字符串第一次出现的索引,如果找不到返回-1
insert插入
length获取长度

package com.study.srv.demo11;

/**
 * @author Wen先森
 * @version 1.0
 * @date 2022/3/11 17:01
 */
public class Demo11 {
    public static void main(String[] args) {
        StringBuffer s = new StringBuffer("hello");
        //增加
        s.append(',');//"hello,"
        s.append("java");//"hello,java"
        s.append("app").append(100).append(true).append(3.14);//"hello,javaapp100true3.14"
        System.out.println(s);
        //删除
        /**
         * 删除索引为>=start&&<end处的字符
         */
        s.delete(5,9);//[5,9) 即删除5~9(不包含9)的索引下的字符
        System.out.println(s);
        //修改
        s.replace(0,5,"world");
        System.out.println(s);
        //查找🔍
        //查找指定的字串在字符串第一次出现的索引,如果找不到,返回-1
        int index=s.indexOf("a");
        System.out.println(index);
        //插入
        s.insert(5,"武当张三丰太极剑法");//即在索引为5的地址插入"武当张三丰太极剑法"
        System.out.println(s);
        //长度
        System.out.println(s.length());
        System.out.println(s);
    }
}

StringBuilder类

  1. 一个可变的字符序列。此类提供了一个与StringBuffer兼容的API,但不保证同步(StringBuilder不是线程安全)。该类被设计用作StringBuffer的简易替换,用在字符串缓冲区被单个线程使用的时候。如果可能,建议优先采用该类,因为在大多数实现中,它比StringBuffer快。
  2. 在StringBuffer上的主要操作类型是append和insert方法,可以重载这些方法,以接受任意类型的数据。

package com.study.srv.demo11;

/**
 * @author Wen先森
 * @version 1.0
 * @date 2022/3/14 11:04
 */
public class Demo14 {
    public static void main(String[] args) {
        //1.StringBuilder继承了AbstractStringBuilder类
        //2.实现了Serializable,说明StringBuilder对象也是可以串行化的(串行化即是:对象可以用于网络传输,也可以保存到文件中)
        //3.StringBuilder是final类,不能被继承
        //4.StringBuilder对象字符序列仍然存放在其父类AbstractStringBuilder的char[]value;
        //因此,字符序列是存放到堆中
        //5.StringBuilder的方法,没有做同步处理,即没有synchronized 关键字,因此在单线程的情况下使用。所以才会线程不安全。
        StringBuilder stringBuilder = new StringBuilder();
    }
}

 为什么StringBuffer是线程安全的,而StringBuilder是线程不安全的?原因就在于synchronized关键字。

@Override
public synchronized StringBuffer append(String str) {
    toStringCache = null;
    super.append(str);
    return this;
}
@Override
public StringBuilder append(String str) {
    super.append(str);
    return this;
}

StringBuilder在append操作时并未使用线程同步,而StringBuffer几乎大部分方法都使用了synchronized关键字进行方法级别的同步处理。

String、StringBuffer和StringBuilder比较

  1. StringBuilder和StringBuffer非常类似,均代表可变的字符序列,而且方法也一样。
  2. String:不可变字符序列,效率低,但是复用率低。
  3. StringBuffer:可变字符序列,效率高(增删)、线程安全。
  4. StringBuilder:可变字符序列,效率最高,但是线程不安全。

String使用注意说明:

        String s="a"; //创建了一个字符串

         s+="b";//实际上原来的"a"字符串对象已经丢弃了,现在又产生一个字符串"ab"。如果多次执行这些改变串内容的操作,会导致大量副本字符串对象存留在内存中,降低效率。如果这样的操作放到循环中,会极大的影响程序的性能。所以,如果我们对String做大量的修改,不要使用String一般使用StringBuffer,如果是单线程的话使用StringBuilder。

package com.study.srv.demo11;

/**
 * @author Wen先森
 * @version 1.0
 * @date 2022/3/14 11:53
 */
public class Demo15 {
    public static void main(String[] args) {
        String s="";
        long startDate=0;
        long endDate=0;
        StringBuffer sb = new StringBuffer();
        StringBuilder sd = new StringBuilder();

        startDate=System.currentTimeMillis();
        for (int i=0;i<50000;i++){
            s+=i;//String拼接
        }
        endDate=System.currentTimeMillis();
        System.out.println("String执行时间为:"+(endDate-startDate));

        startDate=System.currentTimeMillis();
        for (int i=0;i<50000;i++){
            sb.append(String.valueOf(i));//StringBuffer拼接
        }
        endDate=System.currentTimeMillis();
        System.out.println("StringBuffer执行时间为:"+(endDate-startDate));

        startDate=System.currentTimeMillis();
        for (int i=0;i<50000;i++){
            sd.append(String.valueOf(i));//StringBuilder拼接
        }
        endDate=System.currentTimeMillis();
        System.out.println("StringBuilder执行时间为:"+(endDate-startDate));
    }
}

String、StringBuffer、StringBuilder的选择

使用原则,结论:

  • 如果字符串存在大量的修改操作,一般使用StringBuffer或StringBuilder。
  • 如果字符串存在大量的修改操作,并且在单线程情况下,使用StringBuilder。
  • 如果字符串存在大量的修改操作,并且在多线程情况下,使用StringBuffer。
  • 如果字符串很少修改,被多个对象引用,使用String。
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wen先森

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值