【Java 基础】你真的会用 String 吗?


“Java不会字符串,开发就得凉一半”


 本文将对 String 进行稍微深入全面一点的学习,大佬请回避 ~

总所周知

        String 是Java定义好的一个类。定义在java.lang 包中,而 lang 包是java 的核心包,因此使用的时候不需要导包,而且,是个类,证明String就不属于基本类型,Java的基本类型就那 8 个,String是引用类型

创建String对象的方法

方法名说明
public String()创建一个空白字符串对象,不含有任何内容
public String(String original)根据传入的字符串,创建字符串对象
public String(char[] chs)根据字符数组的内容,来创建字符串对象
public String(byte[] bys)根据字节数组的内容,来创建字符串对象
String s = “abc”;直接赋值的方式创建字符串对象,内容就是abc

注意,使用 public String(byte[] bys) 的时候,不是简单的拼接,需要进行ACSII转换,如下

        byte[] bys = {97, 98, 99};
        String s3 = new String(bys);
        System.out.println("s3:" + s3);

输出结果是 abc

String 内存分析

我们看到String类的内部最终是由 char 数组来存储字符串的

现在我们看

String s1 = “abc”;

String s2 = new String("abc")

在内存中的区别

为了节省空间,JVM会在堆区中(JDK 7之前是在方法区中)开辟一个字符串常量池StringTable,用来存放字符串常量,而且是“单例”的,如下

String s3="abc"

String s4="abc"

内存情况如下

所以,我们可以理解为 s1 记录的是 字符串常量 在 字符串常量池中的地址,而 s2 记录的是new String("abc")这个String实例对象在堆中的地址,所以当判断 s1 == s2 时,结果会返回false

因此,如果想比较两个字符串的内容,我们最好使用 equals 方法

StringBuilder & StringBuffer

总所周知,String是不可变的,String不可变不是指

String s="aaa" 后,不能再 s="bbb"

而是说执行上面的代码,不是直接将字符串常量池中的 "aaa" ,改为 "bbb" ,而是会在字符串常量池中新建一个"bbb"常量,然后让引用s指向"bbb"

因为字符串常量的创建会消耗性能,所以如果要对一个String进行频繁的修改,会浪费内存和影响程序效率

在这种场景下,我们可以使用 StringBuilder ,StringBuilder 可以看成是一个容器,创建之后里面的内容是可变的,能极大提高字符串的操作效率

 StringBuilder 的构造方法

方法名说明
public StringBuilder()创建一个空白可变字符串对象,不含有任何内容
public StringBuilder(String str)根据字符串str的内容来创建可变字符串对象

StringBuilder 的常用方法

方法名说明
public StringBuilder append(任意类型)添加数据并返回对象本身
public StringBuilder reverse()反转容器中的内容
public int length()返回长度(字符出现的个数)

public String toString()

实现将 StringBuilder 转换为 String

那么StringBuffer是什么呢?

StringBuffer 和 StringBuilder 几乎相同,只不过 StringBuffer 的方法上都加了同步锁(如下图),因此StringBuffer是线程安全的 ,但是性能较差

字符串拼接的底层原理

        String s1="a";
        String s2=s1+"b";
        String s3="ab";
        System.out.println(s2==s3);

输出 false

        String s1="a";
        String s2="a"+"b";
        String s3="ab";
        System.out.println(s2==s3);

输出 true

为什么呢?

这两个的区别就是在拼接到时候是 纯字符("a"+"b"),还是 存在引用(s1+"b"),纯字符会被优化

本例中创建 String s2="a"+"b" ,在编译的时候,Java会自动优化为 String s2= "ab"

而在JDK8中(JDK7有所不同,但结果一样,不再讲解),创建 String s2=s1+"b" 的过程中,Java会预估一个合适长度(本例为 2)的字符数组,然后分别将 "a" (来自s1) 和 "b" 存入该数组,然后再根据该数组生成 String 对象,相当于是new String,所以此时的s2是指向堆区的,而s3是指向StringTable 的,因此输出 s2==s3 就是fasle

String常用API

最后再总结下String常用API

  • length():返回字符串的长度。
  • charAt(int index):返回指定索引处的字符。
  • substring(int beginIndex, int endIndex):返回一个新字符串,它是此字符串的一个子字符串。
  • equals(Object anObject):比较此字符串与指定对象是否相等。
  • equalsIgnoreCase(String anotherString):比较此字符串与指定字符串是否相等,忽略大小写。
  • indexOf(int ch):返回指定字符在此字符串中第一次出现处的索引。
  • lastIndexOf(int ch):返回指定字符在此字符串中最后一次出现处的索引。
  • startsWith(String prefix):测试此字符串是否以指定的前缀开始。
  • endsWith(String suffix):测试此字符串是否以指定的后缀结束。
  • replaceAll(String regex, String replacement):使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串。
  • split(String regex):根据正则表达式将此字符串拆分为子字符串,并返回这些子字符串的数组。
  • toCharArray():将此字符串转换为字符数组。
  • toLowerCase():将此字符串转换为小写形式。
  • toUpperCase():将此字符串转换为大写形式。
  • hashCode():计算此字符串的哈希码。
  • constructor():创建一个新的字符串对象,其内容是该参数的字符序列。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值