Java中的String类详细总结

总结Java中的String类。



String类

字符串内部是使用字符数组char[] value来存储内容的,字符串是一种线性表(线性表还包括数组、链表等)。


1.类中常用方法

返回类型方法名称作用
charcharAt(int)得到指定下标位置对应的字符
intindexOf(String)得到指定内容第一次出现的下标
intlastIndexOf(String)得到指定内容最后一次出现的下标
intlength()得到一个字符串的字符个数
char[]toCharArray()将一个字符串转换成字符数组
String[]split(String)将一个字符串按照指定内容劈开
byte[]getBytes()将一个字符串转换成字节数组
booleanequals(String)判断两个字符串的内容是否相同
booleanequalsIgnoreCase(String)忽略大小写比较两个字符串的内容是否相同
booleancontains(String)判断一个字符串里面是否包含指定的内容
booleanstartsWith(String)判断一个字符串是否以指定的内容开头
booleanendsWith(String)判断一个字符串是否以指定的内容结尾
StringtoUpperCase()将一个字符串全部转换成大写
StringtoLowerCase()将一个字符串全部转换成小写
Stringreplace(String,String)将某个内容全部替换成指定内容
StringrepalceFirst(String,String)将第一次出现的某个内容替换成指定的内容
Stringsubstring(int)从指定下标开始一直截取到字符串的最后
Stringsubstring(int,int)从下标x截取到下标y-1对应的元素
Stringtrim()去除一个字符串的前后空格

要查看所有String类方法点击这里


2.String类的赋值和intern方法

public class test {
    public static void main(String[] args) {
        String str1 = "hello";
        String str2 = "hello";
        String str3 = new String("hello");
        String str4 = new String("hello");
        System.out.println(str1 == str2);
        System.out.println(str1 == str3);
        System.out.println(str3 == str4);
    }
}

输出:
true
false
false

解释:
采用直接赋值:String str = "字符串字面量"的方式创建字符串对象,会在堆区使用字符串的常量池,若该对象是第一次出现,就在堆中开辟新空间,产生新对象,产生之后将该对象置入字符串的常量池,当下次再次使用该对象时(还是采用直接赋值的方式),若常量池中已有该内容的字符串,直接引用常量池中的对象,将该字符串的地址赋值给str,不再创建字符串。
若使用String str = new String(“字符串字面量”)的方式创建字符串对象,则在堆区的常量池外开辟一块空间,空间里面储存该字符串,将该空间的地址赋值过去str。

字符串的intern方法:

作用:调用这个inern方法,会将产生的字符串对象置入常量池(若不存在则置入),若常量池中已存在该对象,则返回常量中的字符串对象引用(返回地址)。

示例1:字符串比较

    public static void main(String[] args) {
        String str1 = "hello";
        String str2 = "hello";
        String str3 = new String("hello");
//        str3=str3.intern();
        System.out.println(str1 == str2);
        System.out.println(str1 == str3);
    }

输出:
true
false

示例2:在常量池中已有字符串情况下intern()方法使用

    public static void main(String[] args) {
        String str1 = "hello";
        String str2 = "hello";
        String str3 = new String("hello");
        //此时常量池中已有"hello"对象,返回常量池中的hello对象的地址
        str3=str3.intern();
        System.out.println(str1 == str2);
        System.out.println(str1 == str3);
    }

输出:
true
true

示例3:在常量池中没有字符串情况下intern()方法使用

3.1:"abc"字符串第一次出现在intern()方法后面:

    public static void main(String[] args) {
        char[] ch=new char[]{'a','b','c'};
        String s1=new String(ch);
        s1.intern();
        String s2="abc";
        System.out.println(s1 == s2);
    }

输出:
true

图解:
在这里插入图片描述

解释:“abc"出现在intern()字符之后,则调用intern时,常量池中没有"abc”,所以intern()方法的作用是将常量池外面的"abc"移动到常量池内部,s1的地址值不改变,s2赋值时,常量池中已有该字符串,返回该字符串的地址,所以最后输出true。

3.2:"abc"字符串第一次出现在intern()方法前面:

    public static void main(String[] args) {
        String s1=new String("abc");
        s1.intern();
        String s2="abc";
        System.out.println(s1 == s2);
    }

输出:
false

解释:“abc"出现在intern()字符之前,则调用intern时,常量池中已有"abc”,所以intern()方法的作用是返回的是常量池中"abc"的地址,但没有被接收,所以s1的地址值没有改变,返回false。


3.String类的不可变性

当一个字符串的对象产生之后,他的内容就无法修改,这称之为字符串对象的不可变性。

示例:

    public static void main(String[] args) {
        String str = "hello";
        str += "world";
        str += "!!!";
    }

图示:
在这里插入图片描述

因为字符串的不可变性,在执行str += “world"时,会先在堆区的常量池中产生一个"world"对象,然后再产生一个"helloworld"对象,最后把str的引用改为指向"helloworld”,执行str += "!!!"时同理。正是由于字符串对象的不可变性,因此当直接使用字符串对象进行+=操作的时候会产生大量的临时对象,浪费内存!


面试问题:结合String的源码来分析一下为什么唯独字符串对象的内容无法修改?(你怎么理解字符串对象不可变,是如何做到内容无法修改的?)

源码:
在这里插入图片描述

解答:有很多错误的理解在于value数组被final修饰导致内容不能改,其实不是这样的!!!这里final修饰的是引用数据类型,不能修改的是该类型的地址值,而不是里面保存的具体内容。其本质在于在String类中,private关键字将value数组完全封装,且对外没有提供任何获取或者修改该value内容的方法,所以String类外部完全无法拿到这个value数组,因此字符串对象一旦产生,内容无法修改!!!


面试问题:string具有不可变性,Sting类内部有很多操作字符串的方法,如subString截取字符串,替换replace等等方法看起来这不都在修改字符串对象内容吗?

解答:String类的内部提供的所有涉及字符串修改的方法,都会产生新的字符串对象,并不会影响原字符串对象。


4.StringBuilder类和StringBuffer类

String、StringBuilder、StringBuffer区别:

StringStringBufferStringBuilder
执行速度中等
线程安全线程安全线程安全线程不安全
使用场景少量字符串操作多线程环境下的大量操作单线程环境下的大量操作

PS:正常做题大部分情况下都使用StringBuilder。


面试问题:String.StringBuilder、StringBuffer的区别?

1.String的内容无法修改,StringBuffer、StringBuilder的对象内容可以修改,因此我们一般在字符串对象频繁修改的时候使用StringBuilder或StringBuffer类;
2.StringBuilder和StringBuffer的方法使用完全一致,StringBuffer采用同步处理,线程安全,效率较低;
3.StringBuilder采用异步处理,线程不安全,效率较高,开发中若不考虑线程安全问题,一般推荐使用StringBuilder类进行字符串内容的修改。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

木木是木木

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

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

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

打赏作者

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

抵扣说明:

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

余额充值