【Java SE】认识String类

发布于:2022-11-28 ⋅ 阅读:(421) ⋅ 点赞:(0)

作者:✿✿ xxxflower. ✿✿
博客主页:xxxflower的博客
专栏:【Java项目】篇
语录:⭐每一个不曾起舞的日子,都是对生命的辜负。⭐

1.String 类的基本用法

1.1 字符串构造

常用的构造方式有以下三种:
在这里插入图片描述
其他方法请参考:String官方文档
【注意】

  1. String是引用类型,内部并不存储字符串本身。
    在这里插入图片描述
    在这里插入图片描述
  2. 在Java中“”引起来的也是String类型对象。

1.2 String对象的比较

字符串排序。Java中总共提供了4中方式:

  1. ==比较是否引用同一个对象
    注意:对于内置类型,比较的是变量中的值;对于引用类型比较的是引用中的地址。
    在这里插入图片描述
  2. boolean equals(Object anObject) 方法:按照字典序比较

String类重写了父类Object中equals方法,Object中equals默认按照==比较,String重写equals方法后,按照如下规则进行比较,比如: s1.equals(s2)

在这里插入图片描述
3. int compareTo(String s) 方法: 按照字典序进行比较

与equals不同的是,equals返回的是boolean类型,而compareTo返回的是int类型。具体比较方式:

  1. 先按照字典次序大小比较,如果出现不等的字符,直接返回这两个字符的大小差值
  2. 如果前k个字符相等(k为两个字符长度最小值),返回值两个字符串长度差值

在这里插入图片描述
4. int compareToIgnoreCase(String str) 方法:与compareTo方式相同,但是忽略大小写比较在这里插入图片描述

1.3字符串查找

字符串查找也是字符串中非常常见的操作,String类提供的常用查找的方法:
在这里插入图片描述

1.4转化

1.数值和字符串转化

在这里插入图片描述

2.大小写转换

public static void main(String[] args) {
String s1 = "hello";
String s2 = "HELLO";
// 小写转大写
System.out.println(s1.toUpperCase());
// 大写转小写
System.out.println(s2.toLowerCase());
}

3.字符串转数组

public static void main(String[] args) {
String s = "hello";
// 字符串转数组
char[] ch = s.toCharArray();
for (int i = 0; i < ch.length; i++) {
System.out.print(ch[i]);
} S
ystem.out.println();
// 数组转字符串
String s2 = new String(ch);
System.out.println(s2);
}

4.格式化

public static void main(String[] args) {
String s = String.format("%d-%d-%d", 2019, 9,14);
System.out.println(s);
}

1.5字符串替换

在这里插入图片描述
注意事项: 由于字符串是不可变对象, 替换不修改当前字符串, 而是产生一个新的字符串.

1.6 字符串拆分

可以将一个完整的字符串按照指定的分隔符划分为若干个子字符串。
在这里插入图片描述
拆分是特别常用的操作. 一定要重点掌握. 另外有些特殊字符作为分割符可能无法正确切分, 需要加上转义。

在这里插入图片描述

注意事项:

  1. 字符"|“,”*“,”+"都得加上转义字符,前面加上 “\” .
  2. 而如果是 “” ,那么就得写成 “\\” .
  3. 如果一个字符串中有多个分隔符,可以用"|"作为连字符.

在这里插入图片描述

1.7 字符串截取

在这里插入图片描述
在这里插入图片描述
注意事项:

  1. 索引从0开始
  2. 注意前闭后开区间的写法, substring(0, 5) 表示包含 0 号下标的字符, 不包含 5 号下标

1.8其他操作方法

在这里插入图片描述
trim()方法的使用:
在这里插入图片描述

1.9 字符串常量池

1.9.1 创建对象的思考

思考下列代码,为什么s1 s2相同
而s3 s4不同呢?

public static void main(String[] args) {
String s1 = "hello";
String s2 = "hello";
String s3 = new String("hello");
String s4 = new String("hello");
System.out.println(s1 == s2); // true
System.out.println(s1 == s3); // false
System.out.println(s3 == s4); // false
}

在Java程序中,类似于:1, 2, 3,3.14,“hello”等字面类型的常量经常频繁使用,为了使程序的运行速度更快、更节省内存,Java为8种基本数据类型和String类都提供了常量池。
为了节省存储空间以及程序的运行效率,Java中引入了:

  1. Class文件常量池:每个.Java源文件编译后生成.Class文件中会保存当前类中的字面常量以及符号信息
  2. 运行时常量池:在.Class文件被加载时,.Class文件中的常量池被加载到内存中称为运行时常量池,运行时常
    量池每个类都有一份
  3. 字符串常量池

1.9.2字符串常量池(StringTable)

字符串常量池在JVM中是StringTable类,实际是一个固定大小的HashTable(一种高效用来进行查找的数据结构,
后序给大家详细介绍),不同JDK版本下字符串常量池的位置以及默认大小是不同的
在这里插入图片描述

1.9.3再谈String对象创建

不同JDK版本对字符串常量池的处理方式不同

  1. 直接使用字符串常量进行赋值
public static void main(String[] args) {
String s1 = "hello";
String s2 = "hello";
System.out.println(s1 == s2); // true
}

在这里插入图片描述
2.通过new创建String类对象

在这里插入图片描述
我们来分析一下上述代码:
![在这里插入图片描述](https://img-blog.csdnimg.cn/d7a87b0f9
常量池的意义:提升效率
结论:只要是new的对象,都是唯一的。
通过上面例子可以看出:使用常量串创建String类型对象的效率更高,而且更节省空间。用户也可以将创建的字符串对象通过 intern 方式添加进字符串常量池中。
3. intern方法
intern 是一个native方法(Native方法指:底层使用C++实现的,看不到其实现的源代码),该方法的作用是手动将创建的String对象添加到常量池中。

public static void main(String[] args) {
char[] ch = new char[]{'a', 'b', 'c'};
String s1 = new String(ch); // s1对象并不在常量池中
//s1.intern(); // s1.intern();调用之后,会将s1对象的引用放入到常量池中
String s2 = "abc"; // "abc" 在常量池中存在了,s2创建时直接用常量池中"abc"的引用
System.out.println(s1 == s2);
} /
/ 输出false
// 将上述方法打开之后,就会输出true

在这里插入图片描述

面试题:请解释String类中两种对象实例化的区别

  1. String str = “hello” 只会开辟一块堆内存空间,保存在字符串常量池中,然后str共享常量池中的String对象
  2. String str = new String(“hello”)会开辟两块堆内存空间,字符串"hello"保存在字符串常量池中,然后用常量池中的String对象给新开辟
    的String对象赋值。
  3. String str = new String(new char[]{‘h’, ‘e’, ‘l’, ‘l’, ‘o’})现在堆上创建一个String对象,然后利用copyof将重新开辟数组空间,将参数字符串数组中内容拷贝到String对象中

其中上面三行程序分别创建了几个对象?
分别为 :2 3 3种

2.10 字符串的不可变性

String是一种不可变对象. 字符串中的内容是不可改变。字符串不可被修改,是因为:

  1. String类在设计时就是不可改变的,String类实现描述中已经说明了

String类中的字符实际保存在内部维护的value字符数组中,
1. String类被final修饰,表明该类不能被继承
2. value被修饰被final修饰,表明value自身的值不能改变,即不能引用其它字符数组,但是其引用空间中的内容可以修改

  1. 所有涉及到可能修改字符串内容的操作都是创建一个新对象,改变的是新对象。
    final修饰类表明该类不想被继承,final修饰引用类型表明该引用变量不能引用其他对象,但是其引用对象中的内容是可以修改的。

1.11 字符串修改

注意:尽量避免直接对String类型对象进行修改,因为String类是不能修改的,所有的修改都会创建新对象,效率非常低下。
因为中间会创建许多临时变量。
尽量避免对String的直接需要,如果要修改建议尽量使用StringBuffer或者StringBuilder。

2.StringBuilder和StringBuffer

2.1StringBuilder的介绍

由于String的不可更改特性,为了方便字符串的修改Java中又提供StringBuilder和StringBuffer类。这两个类大部分功能是相同的。

方法 说明
在这里插入图片描述

从上述例子可以看出:String和StringBuilder最大的区别在于String的内容无法修改,而StringBuilder的内容可以修改。频繁修改字符串的情况考虑使用StringBuilder。
注意:
String和StringBuilder类不能直接转换。如果要想互相转换,可以采用如下原则:

String变为StringBuilder: 利用StringBuilder的构造方法或append()方法
StringBuilder变为String: 调用toString()方法。

面试题:
String、StringBuffer、StringBuilder的区别

  1. String的内容不可修改,StringBuffer与StringBuilder的内容可以修改.
  2. StringBuffer与StringBuilder大部分功能是相似的
  3. StringBuffer采用同步处理,属于线程安全操作;而StringBuilder未采用同步处理,属于线程不安全操作
本文含有隐藏内容,请 开通VIP 后查看