Bootstrap

JavaSE——常用类库(String类)

第1节 常用类库——String

因为String相对之前的类来说更加常用一些,所以对字符串类进行专门的整理。

1. 概述

   String类表示字符串,Java中的所有字符串文字都实现为此类的实例。

字符串是不变的,它们的值在创建后无法更改 。因为它的创建是通过一个由private final修饰的byte数组value来实现的,一旦赋值,不可更改。
在这里插入图片描述
在这里插入图片描述
如果想要使用可变字符串,后面的StringBufferStringBuilder会介绍。

因为String对象是不可变的,所以可以共享它们。 这句话怎么理解?需要结合下面的赋值方式来理解。

2. String的两种赋值方式:

  • 一种为直接赋值,因为一个字符串可以表示一个String类的对象,
String text = "123";
  • 第二种为通过关键字new调用String的构造方法赋值:
String text3 = new String("123");

先来看一段代码,体会一下两者的区别:

package com.kaikeba.coreclasslibrary.string;

public class Demo {
    public static void main(String[] args) {
        String text = "123";
        String text2 = "123";
        String text3 = new String("123");
        System.out.println(text == text2);
        System.out.println(text == text3);
    }
}

结果为:
true
false

这里就用到了1中说的因为String对象是不可变的,所以可以共享它们。

因为String在内存中存储在永久代中(后续会介绍),该内存不会去进行GC,所以没有必要给同样的字符串分出两块地址,使用第一种赋值方式,并不会开辟出两块地址,而是会将两个引用对象指向同一个地址 ,所以text和text2就是一样的值,这就是共享的意思。 但是第二种赋值方式,使用new关键字强制地开辟了一块内存,所以地址值不一样。

给一张图会更直观一些,str1就是上述代码的text3,str2和str3就是上述代码的text和text2。
在这里插入图片描述

3. 字符串常量池

3.1 方法区(Method Area)

方法区(Method Area),又称永久代(Permanent Generation),又称非堆区(Non-Heap space)。

方法区是被所有线程共享的:

    - 所有字段和方法字节码,以及一些特殊方法和构造函数,接口代码也在此定义。简单说,所有定义的方法的信息都保存在该区域,此区域属于共享区间

    - 该区域存储的是:静态变量+常量+类信息(构造方法/接口定义)+运行时常量池。

但是,实例变量(对象)存在堆内存中,和方法区无关。

以上,只是逻辑上的定义,在HotSpot中,方法区仅仅只是逻辑上的独立,实际上还是包含在Java堆中,也就是说,方法区在物理上属于Java堆区中的一部分,而永久区(Permanent Generation)就是方法区的实现。

3.2 堆(heap)

一个JVM实例只存在一个堆内存,堆内存的大小是可以调节的。类加载器读取了类文件后,需要把类、方法、常变量放到堆内存中,保存所有引用类型的真实信息,以方便执行器执行。

堆 在逻辑上分为三部分(Perm):

  • 新生代 (Young Generation,常称为YoungGen):刚创建的内存存储位置,频繁地进行GC,若一个对象连续经过15次GC还没有被回收,它就会被放到老年代。位于堆空间

    - Eden区 :存储新创建的对象;

    - Survior区 (幸存区):存储GC次数1~14次的对象。

  • 老年代 (Old Generation。常称为OldGen、TenuringGen):GC的频次较低,位于堆空间

  • 永久代 (Permanent Generation,常称为PermGen):是一个常驻内存区域,用于存放JDK自身所携带的Class、Interface的元数据,也就是说它存储的是运行环境必须的类信息,被装在进此区域的数据是不会被垃圾回收器回收的,关闭JVM才会释放此区域所占用的内存。(不进行GC,类、方法、常量、静态修饰的内容都会放在永久代位于非堆空间。

4. 构造方法

在这里插入图片描述

最常用的当然还是直接给一个字符串而不是用构造器。

此外还需要注意三个构造方法:

1、构造一个新的String并用指定的解码集解码,读入不同集的字符串会需要。

在这里插入图片描述

2、3:用一个StringBufferStringBuilder对象来构造String,这个可以实现StringBufferStringBuilderString类的转变。

在这里插入图片描述

5. 各种方法

String类的方法很多。。。

1、返回指定索引处的char值,这还是很常用的,因为Java字符串不能像数组一样使用[索引]来访问,charAt方法就是替代。IntStream类先跳过,没学过。

在这里插入图片描述

2、返回Unicode的方法,目前还没用过。

在这里插入图片描述

3、按字典顺序比较两个字符串,不用多解释。

在这里插入图片描述

4、拼接字符串,返回拼接后的结果。

在这里插入图片描述

5、功能很明确

在这里插入图片描述

6、字符串与字符序列或StringBuffer比较是否相等。

在这里插入图片描述

7、判断字符串是否以指定的后缀结尾。

在这里插入图片描述

8、比较是否相等

在这里插入图片描述

9、指定的格式字符串和参数返回格式化字符串,没用过。

在这里插入图片描述

10、将字符串变为数组

在这里插入图片描述

11、返回字符串的哈希码

在这里插入图片描述

12、返回字符第一次出现的索引

在这里插入图片描述

13、啥是规范表示?

在这里插入图片描述

14、判断字符串是否为空

在这里插入图片描述

15、将字符序列按照指定的连接符拼接为字符串,这个很常用

在这里插入图片描述

16、返回字符最后一次出现的索引

在这里插入图片描述

17、返回字符串的长度,常用

在这里插入图片描述

18、现在不懂

在这里插入图片描述

19、判断字符串是否与指定的正则表达式匹配,没用过

在这里插入图片描述

20、不懂

在这里插入图片描述

21、判断两个字符串区域是否相等

在这里插入图片描述

22、返回该字符串重复了count次的字符串

在这里插入图片描述

23、字符串替换

在这里插入图片描述

24、字符串拆分,按照指定的拆分符

在这里插入图片描述

25、判断字符串是否以指定前缀开头

在这里插入图片描述

26、去除头尾的空格

在这里插入图片描述

27、取子字符串

在这里插入图片描述

28、将字符串转为字符数组

在这里插入图片描述

29、大小写

在这里插入图片描述

30、和strip类似,去除的不只空格

在这里插入图片描述

31、将数据类型转为字符串,注意是静态方法,直接用类名调用

在这里插入图片描述

6. 字符串拼接问题

观察如下代码:

package com.kaikeba.coreclasslibrary.string;

public class Demo {
    public static void main(String[] args) {
        String t1 = "锄禾日当午";
        String t2 = "汗滴禾下土";
        String t3 = "床前明月光";
        t1 = t1+t2+t3;
        System.out.println(t1);
    }
}

它在内存中的细节如下图所示:

在这里插入图片描述

通过“+”运算符会产生很多中间字符串,而且没有引用,另外因为字符串是存在字符串常量池,也就是在永久代中的, 所以GC不会来回收它们,这样就导致了一个严重的问题,内存占用过大

7. StringBuffer、StringBuilder类

为了解决上述的问题,就需要用到另外两个类StringBufferStringBuilder。这两个都是长度、内容可变的字符序列类型,字符串缓冲区类似于String,但是可以进行修改。它们两个方法上上很相似,主要区别是:StringBuffer是线程安全的,StringBuilder是线程不安全的,单个线程情况下,StringBuilder更快,线程的问题后续再介绍。

7.1 构造方法

在这里插入图片描述

在这里插入图片描述

两者是一样的,重点关注将String类直接转为相应的类的构造方法。

7.2 方法
   最常用的就是append和insert方法,插入新数据:

在这里插入图片描述

在这里插入图片描述

有加入就有删除:

在这里插入图片描述

还有设置:

在这里插入图片描述

注意获取长度是capacity:

在这里插入图片描述

还有一个需要特别记忆,翻转操作,String类没有:

在这里插入图片描述

还有一个需要特别注意,它们的toString方法已经被重写,调用toString直接将这两类转为String返回:

在这里插入图片描述

其他的方法很多String类的都有。

看一个简单例子:

package com.kaikeba.coreclasslibrary.string;

public class Demo2 {
    public static void main(String[] args) {
        //线程不安全的实现
        StringBuilder sb = new StringBuilder();
        //StringBuffer 线程安全的实现
        sb.append("1");
        sb.append("2");
        sb.append("3");
        String text = sb.toString();
        System.out.println(text);
    }
}


结果为:
123

;