String,StringBuffer,StringBuilder知识梳理

文章详细介绍了Java中String类的特点,如不可变性,以及创建和修改String对象的方式。提到了String常用的实例方法,如length()、equals()和concat()等。另外,对比了String与可变的StringBuilder和StringBuffer类,包括它们的转换方法和在多线程环境下的适用性。还讨论了这些类在字符串操作性能上的差异。
摘要由CSDN通过智能技术生成

String类

是不可变的对象,即每次要对String对象进行修改时,都会重新创建一个新的String对象,然后指向这个新对象。

创建方式有两种:

1.          String s = "abc";         //先查看常量池有无"abc"数据空间,如果有直接指向,没有就在常量池中创建一个,然后指向

2.          String s = new String ("abc");        //现在堆中创建一块空间,维护了value属性,然后这块空间指向常量池中的"abc",如果常量池没有,同上

String常用方法:

int length():        返回字符串的长度


char charAt(int index):        返回指定索引处的字符


boolean isEmpty():        判断字符串是否为空


String toLowerCase():        将字符串中的所有字符转换为小写


String toUpperCase():        将字符串中的所有字符转换为大写


String trim():        返回字符串的副本,去掉前导空白和尾部空白,中间的空白不会被去掉


boolean equals(Object obj):        比较字符串的内容是否相同


boolean equalsIgnoreCase(String anotherString):        忽略大小写,比较字符串的内容是否相同


String concat(String str):        将指定字符串连接到此字符串的结尾,等价于用“+”


int compareTo(String anotherString):        比较两个字符串的大小


String substring(int beginIndex):        返回从beginIndex到末尾的子字符串


String substring(int beginIndex, int endIndex):        返回从beginIndex到endIndex-1的子字符串,不包括endIndex

boolean endsWith(String suffix):         判断字符串是否以指定的后缀结束


boolean startsWith(String prefix):        判断字符串是否以指定的前缀开始


boolean startsWith(String prefix, int toffset):        判断字符串在指定索引开始的子字符串是否以指定前缀开始


boolean contains(CharSequence s):        判断当前字符串中是否包含指定的字符串

int indexOf(String str):        返回指定子字符串在当前字符串中第一次出现处的索引


int indexOf(String str, int fromIndex):        返回从指定的索引后,指定子字符串在当前字符串中第一次出现处的索引


int lastIndexOf(String str):        返回指定子字符串在当前字符串中最后一次出现处的索引


int lastIndexOf(String str, int fromIndex):        返回从指定的索引后,指定子字符串在当前字符串中最后一次出现处的索引
注:indexOf和lastIndexOf方法如果未查找到指定子字符串时,返回值都为-1。

String replace(char oldChar, char newChar):        替换当前字符串中指定的子字符串


String[] split(String regex):        根据指定的符号拆分当前字符串,然后返回一个String数组

String和char[]相互转换

        //String-->char[]
        String s1 = new String("123jslas");
        char [] c1 = s1.toCharArray();
        System.out.println(c1);

        //char[]-->String
        char [] c2 = {79,'c','s','a'};
        String s2 = new String (c2);
        System.out.println(s2);

String和byte[]互相转换,使用String的getBytes方法,同理

特性:

String a = "abc";    //创建了一个a对象
String b = "ee";    //创建了一个b对象
String c = a+b;   //创建了三个对象,分别是"abcee"这个字符串常量,Stringbuilder对象,String对象

因为String t1 = "a"+"b"是常量相加,看的是池

而String t2 = a+"123"是有变量参与的相加,是在堆中。这种相加底层是StringBuilder t2 = new StringBuilder();t2.append(a);t2.append("123"); t2是在堆中。

总结:当变量与字面量或变量与变量进行拼接时,会在堆中创建一个StringBuilde对象,然后使用StringBuilder的append()方法将变量与字面量或变量与变量进行拼接,最后调用toString()方法转成String对象。


StringBuffer (线程安全)

底层也是用一个数组来存储字符串的值

如果调用无参构造器,数组长度默认为16

 

调用有参构造函数创建一个StringBuffer对象时,数组长度为“当前对象值的长度+16”

 在用append添加字符常量时,先判断添加之后的长度是否大于目前的容量,如果大的话,就要进行扩容

 

 

扩容
扩容的逻辑就是创建一个新的 char 数组,将现有容量扩大一倍再加上2,如果还是不够大则直接等于需要的容量大小。扩容完成之后,将原数组的内容复制到新数组,最后将指针指向新的 char 数组。

这个是Arrays类提供的静态方法,将原来的数组扩充到newLength长度,然后将原来的数据拷贝过去,可以从源码看出,它首先创建出一个新的字符数组,然后使用System的静态方法arraycopy将原来的数据拷贝到新的数组,然后返回新的数组。

StringBuffer类常用方法

增 append

 s.append(",");         s.append("小张").append("小王").append(11.4).append(true);

删 delete(start,end)

改 replace(start,end,String)

s.replace(11,14,“马化腾”);

查 indexOf        //查找指定的子串在字符串中第一次出现的索引,找不到返回-1

int indexof = s.indexOf("马化腾");

插 insert

s.insert(9,"小张");

获取长度 length

String,StringBuffer相互转换

        //String -- > StringBuffer
        //方法1
        String s1 = new String("demaxiya");
        StringBuffer b1 = new StringBuffer(s1);
        System.out.println(b1);
        //方法2
        StringBuffer b2 = new StringBuffer();
        b2.append(s1);

        //StringBuffer -- > String
        //方法1
        StringBuffer b3 = new StringBuffer("qigeai");
        String s3 = b3.toString();
        System.out.println(s3);
        //方法2
        String s4 = new String(b3);
        System.out.println(s4);

 

String、StringBuffer和StringBuilder的异同
相同点:底层都是通过char数组实现的
不同点:

String对象一旦创建,值不能修改的,如果要修改,会重新开辟内存空间来存储修改之后的对象;而StringBuffer和StringBuilder对象的值是可以被修改的;
StringBuffer几乎所有的方法都使用synchronized实现了同步,线程比较安全,在多线程系统中可以保证数据同步,但是效率比较低;而StringBuilder 没有实现同步,线程不安全,在多线程系统中不能使用 StringBuilder,但是效率比较高。
如果我们在实际开发过程中需要对字符串进行频繁的修改,不要使用String,否则会造成内存空间的浪费;当需要考虑线程安全的场景下使用 StringBuffer,如果不需要考虑线程安全,追求效率的场景下可以使用 StringBuilder。
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值