String类进阶简单梳理

String类进阶简单梳理

1、String类简单介绍

String类不是Java的8大基本数据类型,它是属于java.lang包下的。

同时由于String类是有final关键字修饰的,所有它不能被继承,不能有子类。

String类的底层是char数组,也是final关键字修饰的,所以它不能被更改。

2、String类的存储原理

String类对象有个特殊的创建方式,也就是直接指定String类对象等于一个字符串,像这样:String str="HelloWorld"。或者使用String类的构造方法,像这样String str=new String("HelloWorld")。但是这两者在内存中有很大的区别。

  • 直接等于字符串String str=“HelloWorld”

    JVM中是先创建在常量池里创建了"HelloWorld"这个字符串,然后str存的就是这个字符串对象的地址,所以str实际上是这个字符串的引用。这个字符串只要被创建出来就不能被改变或者消失会一直存在。

    在这里插入图片描述

    所以,如果另外一个字符串str2也直接等于"HelloWorld",那么str和str2如果比较地址,那么他们两个是一样的(内容也一样)。

    		String str="Hello,World";
            String str2="Hello,World";
            System.out.println(str == str2);//true
    

    内存图:

    在这里插入图片描述

    只要某个字符串被创建,他们它就会一直存在,不会消失。所以拼接字符串的时候,拼接两个字符串实际上会在常量池中创建3个字符串

    String str="Hello,World"+"->Java";//"Hello,World","->Java","Hello,World->Java"
    

    内存图:

    在这里插入图片描述

  • 使用构造方法String str=new String(“HelloWorld”)

    JVM中仍然是先在常量池中创建了字符串常量,然后new出来的String类型的对象存在堆中,然后栈中的str存的是刚刚new出来的String对象的内存地址。

    在这里插入图片描述

    所以,如果两个通过new String出来的String对象通过比较的地址的方式比较是不相等的。

            String str1 = new String("HelloWorld");
            String str2 = new String("HelloWorld");
            System.out.println(str1 == str2);//false
    

    内存图:

    在这里插入图片描述

总结:直接等于字符串的方式新建出来的是字符串常量,无法被改变,并且即使创建了一样的字符串,那么依旧是相等的。如果通过new String的方法new出来的字符串变量是指向堆中的String类对象的,即使字符串内容相等,但是对象不相等。所以字符串比较内容尽量中equals()方法比较。

3、String类的构造方法

String();								    //空字符串
String(byte[] bytes); 						//通过byte数组创建字符串
String(byte[] bytes, int offset, int length); //offset是数组的第几个开始,length是长度
String(char[] value);						//通过char数组创建字符串
String(char[] value, int offset, int count);  //offset是数组的第几个开始,length是长度
String(String original);					//用String对象创建字符串
String(StringBuffer buffer);				//用StringBuffer创建字符串
String(StringBuilder builder);				//用StringBuilder创建字符串

4、String类的常用方法

char charAt(int index);						//返回指定索引的char值
int compareTo(String anotherString);		//比较两个字符串(通过ASCII码)
String concat(String str);					//将str添加到该字符串末尾
boolean contains(CharSequence s);			//判断该字符串是否包含字符串s
boolean endsWith(String suffix);			//判断该字符串是否以suffix字符串结尾
boolean equals(Object anObject);			//将两个字符串进行比较
byte[] getBytes();							//将该字符串转换为byte数组
int indexOf(String str);					//返回第一次出现str字符串的索引
boolean isEmpty();							//判断该字符串是否为空
int lastIndexOf(String str);				//返回最后一次出现str字符串的索引
int length();								//返回该字符串的长度
String replace(String oldString, String newString);	//将该字符串中的oldString字符替换成newString字符
String[] split(String regex);				//利用正则或者字符串来分割该字符串
boolean startsWith(String prefix);			//判断该字符串是否以prefix字符串开始
String substring(int beginIndex, int endIndex);//截取字符串从beginIndex开始到endIndex结束,endIndex默认是结尾
char[] toCharArray();						//将该字符串转换为char数组
String toLowerCase();						//将字符串全部转换为小写
String toUpperCase();						//将字符串全部转换为大写
String trim();								//将前导或结尾的空字符串去掉

5、valueOf()方法

valueOf( )方法可以将所有的基本数据类型转换为字符串类型,在println( )的底层其实也就是调用了对象的valueOf( )方法

6、StringBuffer

如果通过String类来拼接字符串的话,每次拼接都会创建新的字符串对象到常量池里,很浪费内存空间,所以java.lang.StringBuffer就是专门用来拼接字符串的,底层同样是char数组,但是没有final关键字修饰,所以它是可变的。默认的容量是16,可以通过构造方法来指定容量大小。底层是可扩容的,如果超过了大小就会自动扩容,同时是线程安全的,方法都有sychronized关键字修饰。

通过append( )方法来添加元素,每次添加都是到末尾,可以添加基本数据类型和Object类型等。执行append( )方法会调用String类的valueOf( )方法,然后valueOf( )方法又会调用类对象的toString方法,所以我们需要重写toString方法。

通过insert(int index,Object o)向指定位置插入元素。

7、StringBuilder

跟StringBuffer差不多,但是线程不安全,方法都没有sychronized关键字修饰。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值