【Java常用类】String类

文章目录

  • 一、概述
  • 二、剖析
    • 2.1 结构剖析
    • 2.2 创建剖析
    • 2.3 String特性
  • 三、String类的常用方法

一、概述

Java 没有内置的字符串类型, 而是在标准 Java 类库中提供了一个预定义类,很自然地叫做 String。每个用双引号括起来的字符串都是String类的一个实例。
String对象用于保存字符串,也就是一组字符序列,字符串常量对象是用双引号括起的字符序列,例如:"你好""14.31""toy"等。

字符串字符使用的是Unicode字符编码,一个字符(不区分字符汉字等)占两个字节。

二、剖析

2.1 结构剖析

【Java常用类】String类_第1张图片

String类是一个final类,不能被其他类继承;根据String类的源码可以看到,字符串是使用一个char类型的数组存储的,并且是final修饰的 (一旦赋值,不可修改,数组中的字符可以修改,内存地址是不变的)

【Java常用类】String类_第2张图片

2.2 创建剖析

创建String对象有两种方式:

第一种,直接赋值:

String s = "arbor";

先从常量池查询是否有"arbor"的数据空间,如果有,直接指向;如果没有,则在常量池中创建,然后指向。变量s的最终指向是常量池的空间地址。

第二种,调用构造器:

String s = new String("arbor");

先在堆中创建空间,里面会有value属性,value属性指向的是常量池的"arbor"的数据空间,如果常量池中没有,会在常量池中创建,并且指向给value属性。变量s的最终指向是堆中的对象空间地址,而对象中的value属性指向的是常量池的空间地址。

【Java常用类】String类_第3张图片

2.3 String特性

① String是一个final类,代表不可变的字符序列。
② 字符串是不可变的,一个字符串对象一旦被分配,内容是不变的。

比如下面代码:

String a = "abc";
a = "xyz";

【Java常用类】String类_第4张图片

③ 当执行String a = "hello" + "abc";时,编译器会做一个优化,如果"hello""abc"没有其他变量引用,则直接会创建"helloabc",而不是分开创建
常量相加,值在池中

④ 下面第三行代码的执行流程:
(1) 会先创建一个StringBuilder对象,通过追溯源码可以看到,会创建一个长度为16的StringBuilder对象。
在这里插入图片描述
(2) 调用StringBuilder中的append方法,先将a的值加入到StringBuilder对象中。
【Java常用类】String类_第5张图片
(3) 再次调用append方法,将b的值也加入到StringBuilder对象中。
【Java常用类】String类_第6张图片
(4) 调用StringBuilder中的toString方法,将StringBuilder转换为字符串的形式返回。
【Java常用类】String类_第7张图片
因为StringBuilder初始会创建空间为16的字符数组,而ab的总字符数是8个,所以这里会返回字符数组中的前8个值。
【Java常用类】String类_第8张图片
执行完毕!!
因为toString方法是new了一个String对象,所以c变量指向的是堆中的String对象,而这个String对象的value属性指向的是常量池中的"helloabc"
常量池中最终会有三个值,分别是"hello""abc""helloabc"
变量相加,对象在堆中

String a = "hello";
String b = "abc";
String c = a + b;

⑤ 字符串是“值传递”,因为字符串是常量。可以看下面代码:
当调用change方法时,是把aaa.str的在堆中的String对象地址传进来了,此时change方法中的局部变量straaa.str的指向是一样的,当执行str = "java";时,只是把局部变量str的指向改变了,并没有改变aaa.str的指向,所以下面的代码输出arbor

public class String01 {

    String str = new String("arbor");

    public void change(String str) {
        str = "java";
    }

    public static void main(String[] args) {
        String01 aaa = new String01();
        aaa.change(aaa.str);
        System.out.println(aaa.str);
    }
}

三、String类的常用方法

判断功能的方法

equals(Object other):判断字符串内容是否相等,区分大小写;如果字符串与 other 相等,返回 true。

equalsIgnoreCase(String other):判断字符串内容是否相等,不区分大小写;如果字符串与 other 相等(忽略大小写),返回 true。

startsWith(String prefix):如果字符串以 suffix 开头,则返回 true。
endsWith(String suffix):如果字符串以 suffix 结尾,则返回 true。

contains(String str):判断一个字符串中有没有str子串,有的话为true。

compareTo(String anotherString):比较两个字符串的大小,前者大返回正数;后者大返回负数;如果相等,则返回0。

如果两个字符串长度相同,字符也相同,返回0;
如果字符不同(不考虑长度),但是字符可以区分大小,返回的是字符的差值,比如:abc 和 acd,abc 和 acda。
如果字符相同,但是长度不同,返回的是字符串长度的差值,比如:abc 和 ab,xy 和 xyz。


获取功能的方法

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

concat(String str):将str拼接到原始字符串后面。

charAt(int index):获取该字符串某处索引的字符。

indexOf(...):获取字符(也可以是字符串)在字符串中第一次出现的索引,索引从0(或者可以自己指定)开始,如果找不到,返回-1。

lastIndexOf(...):获取字符(也可以是字符串)在字符串中最后一次出现的索引,索引从0(或者可以自己指定)开始,如果找不到,返回-1。

substring(...):截取指定范围的子串。只传入一个参数的话是从该数字的索引到最后一个字符。传入两个参数的话是从第一个索引值到第二个索引值,但是不包括第二个索引值,包头不包尾。


转换功能的方法

toCharArray():将字符串转换为字符数组。

getBytes():使用平台的默认字符集将该String编码转换为新的字节数组。

replace(String str, String str2):返回一个新字符串。将一个字符串中的str更换为str2。

toLowerCase():返回一个新字符串。将原始字符串中的大写字母改为小写。
toUpperCase():返回一个新字符串。将原始字符串中的小写字母改为大写。

trim():返回删除了原始字符串头部和尾部的空格的新字符串。

format(...):格式化字符串。

占位符:每一个以字符开始的格式说明符都用相应的参数替换。
最常用的占位符:
%s :表示使用字符串替换
%d :表示使用整数替换
%x.f :表示使用浮点数替换,x表示一个数字,比如2的话,就说明是保留两位小数,并且进行四舍五入
%c :表示使用字符替换

public static void main(String[] args) {
    String name = "乔木先生";
    int age = 18;
    String info = "我的名字是%s,年龄是%d";
    String formatStr = String.format(info, name, age);
    System.out.println(formatStr);
}

输出结果:
【Java常用类】String类_第9张图片


分割功能的方法

split(...):根据传入的正则表达式将字符串分割,返回一个字符串数组。有些字符需要使用\转义。

join(...):返回一个新字符串,用给的字符连接所有元素。

String all = String.join(" / ", "S", "M", "L", "XL"); 
// all is the string "S / M / L / XL"

其他方法

intern():如果池中已经包含一个等于此String对象的字符串,则返回池中的字符串。否则,将此字符串添加到池中,并且返回此String对象的引用。
该方法最终返回的是常量池的对象地址。

你可能感兴趣的:(JavaSE,java,开发语言,后端)