【Java】String类(超级详细!!!)

你是否真正吃透了 Java 的 String 类?本文从基础到进阶,梳理关键知识点,帮你夯实 String 类使用能力。

1.String类

在JAVA中被双括号括起来的就是String类,在JAVA中没有'\0'的说法,String类是一个引用类型,本文主要是在Sting类的内部方法的学习以及使用。

2.比较两个字符串的大小比较

2.1 Comparable

Comparable 是一个接口,用于定义对象的自然排序规则。实现了 Comparable 接口的类,可以通过其compareTo 方法来比较两个对象的大小,从而支持排序操作(如:Arrays.sort())

2.1.1 compareTo

compareTo 方法通过返回值定义两个对象(this 和参数 o)的大小关系:

返回负数:this < o(当前对象小于参数对象)

返回 0:this == o(当前对象等于参数对象)

返回正数:this > o(当前对象大于参数对象)

Comparable 接口的典型用途是:

  1. 让类的对象支持自然排序(如数字从小到大、字符串按字典序)。
  2. 使对象可以直接作为 TreeSet(有序集合)的元素或 TreeMap 的键(自动按排序规则存储)。
  3. 支持通过 Arrays.sort() 对对象集合 / 数组进行排序。

示例:

java 复制代码
String s1 = "apple";
String s2 = "banana";
String s3 = "apple";

System.out.println(s1.compareTo(s2)); // -1(a在b前)
System.out.println(s2.compareTo(s1)); // 1(b在a后)
System.out.println(s1.compareTo(s3)); // 0(内容相同)

2.2 Comparator

在 Java 中,Comparator 是一个用于定义对象排序规则的函数式接口(位于 java.util 包),它与 Comparable 不同:Comparable 是类自身实现的 "内部 比较器"(定义自然排序),而 Comparator 是 "外部 比较器",允许在不修改原类的情况下,为类定义额外或临时的排序规则。核心方法为compare

2.2.1 compare

与 Comparable 的 compareTo 类似,compare 方法的返回值定义排序逻辑:

返回负数:o1 < o2(o1 应排在o2 前面)

返回 0:o1 == o2(o1 和 o2 排序位置相同)

返回正数:o1 > o2(o1 应排在 o2 后面)

Comparator 适用于以下场景:

  1. 为未实现 Comparable 接口的类定义排序规则。
  2. 为已实现 Comparable的类提供额外的排序方式(不改变其默认的自然排序)。
  3. 作为参数传递给排序方法(如Collections.sort()、Arrays.sort())或有序集合(如 TreeSet、TreeMap),指定排序逻辑。

示例:

java 复制代码
Comparator<String> comp = String::compareToIgnoreCase;

System.out.println(comp.compare("Apple", "apple")); // 0(忽略大小写相等)
System.out.println(comp.compare("Banana", "apple")); // 1(B的ASCII大于A)
System.out.println(comp.compare("cat", "Dog")); // -1(c的ASCII小于D)

2.3 equals

在 Java 中,String的equals()方法用于比较两个字符串的内容是否相等 ,而==比较的是对象的内存地址

equals()是Object类的方法,String重写了它,实现逻辑为:先判断是否为同一对象,再比较长度和每个字符是否一致

示例:

java 复制代码
String s1 = "hello";
String s2 = new String("hello");
String s3 = "hello";

// 比较内容是否相同
System.out.println(s1.equals(s2)); // true(内容一致)
System.out.println(s1.equals(s3)); // true(常量池同一对象)
System.out.println(s1.equals("hello")); // true(字面量比较)

2.4 Comparable、Comparator 、 equals和==的关系

类型 作用 核心方法 / 逻辑 所属范畴
Comparable 定义类的自然排序规则 int compareTo(T o) 类自身实现(内部比较)
Comparator 定义类的外部 / 临时排序规则 int compare(T o1, T o2) 外部实现(外部比较)
equals 判断两个对象是否逻辑相等 boolean equals(Object obj) 对象的逻辑相等性判断
== 判断两个对象的内存地址是否一致 == /

3.字符串的查找

3.1 字符串转字符

java 复制代码
String str = "Hello";
char ch = str.charAt(0); // 输出H

上述代码是从字符串str中获取第0个下标的字符赋值给ch。

3.2 在字符串中找字符或字符串并返回下标

java 复制代码
int i1 = str.indexOf('l',4); // 返回-1 找不到就返回-1
int i2 = str.indexOf('l',3); // 返回3
int i3 = str.indexOf("ll"); // 返回2
int i4 = str.indexOf("ll",3); // 返回-1

i1是在str中找l字符,从第四个下标开始找,找不到就返回-1.

i2找到了就返回找到的下标

i3是可以在字符串中找字符串,并返回其下标

i4是从字符串str的3下标开始找子字符串,找不到就返回-1

java 复制代码
int i5 = str.lastIndexOf('l'); // 3
int i6 = str.lastIndexOf('l',2); // 2
int i7 = str.lastIndexOf("ll"); // 2
int i8 = str.lastIndexOf("ll",3); // 2

i5是在str中从后向前 找l字符,从最后一个下标开始找,找不到就返回-1.

i6是在str中从3下标开始向前 找l字符,

i7是可以在字符串中从后向前 找字符串,并返回 其下标

i8是从字符串str的3下标开始从后向前 找子字符串,找不到就返回-1.

但是如果是从2开始的话,也就是从2下标开始向前走的,但是这个子串ll的起始位置 是2,是可以找到这个ll子串的所以返回的是2.

4.字符串的转换

顾名思义就是将对象转换成字符串

java 复制代码
String str = String.valueOf("abc");// abc
String str1 = String.valueOf(1); // 1
String str2 = String.valueOf(19); // 19

将对象转换成字符串,str1这里发生了装箱,将int->Integer.

在输出的时候使用"..." + 变量就是调用了valueOf方法

转换 char[] 有特殊重载:String.valueOf(char[] arr) 会将字符数组拼接为字符串(如 valueOf(new char[]{'a','b'}) → "ab")


4.1 包装类.valueOf () ------ 基本类型 / 字符串转包装类对象

Integer.valueOf(int i) 会缓存 -128~127 之间的整数对象 ,重复调用时返回同一个对象(而非新建),这是面试高频考点!

java 复制代码
// 1. 基本类型 → 包装类(带缓存)
Integer i1 = Integer.valueOf(100);
Integer i2 = Integer.valueOf(100);
System.out.println(i1 == i2);  // true(缓存命中,同一对象)

Integer i3 = Integer.valueOf(200);
Integer i4 = Integer.valueOf(200);
System.out.println(i3 == i4);  // false(超出缓存范围,新建对象)

// 2. 字符串 → 包装类(需字符串格式匹配,否则抛异常)
Integer i5 = Integer.valueOf("123");  // 字符串"123"→Integer对象123
Long l1 = Long.valueOf("456");        // 字符串"456"→Long对象456
Double d1 = Double.valueOf("3.14");   // 字符串"3.14"→Double对象3.14
  • Double.valueOf():无缓存(因为浮点数范围太大,无法缓存),每次调用都会新建对象;
  • 与 new Integer(100)的区别:new 关键字强制新建对象,不使用缓存;valueOf() 优先使用缓存,效率更高。

4.2 BigDecimal.valueOf () ------ 浮点数转 BigDecimal(推荐)

  • BigDecimal 有两个常用构造:new BigDecimal(double d) 可能因浮点数精度问题出错,而BigDecimal.valueOf(double d) 会先将浮点数转为字符串,避免精度丢失,是推荐用法。
java 复制代码
// 错误示例:new BigDecimal(double) 精度丢失
BigDecimal bd1 = new BigDecimal(0.1);
System.out.println(bd1);  // 输出:0.1000000000000000055511151231257827021181583404541015625

// 正确示例:valueOf(double) 避免精度丢失
BigDecimal bd2 = BigDecimal.valueOf(0.1);
System.out.println(bd2);  // 输出:0.1(本质是调用 new BigDecimal("0.1"))

4.3 高频面试考点

  1. String.valueOf(null) 和 null.toString() 的区别:前者返回 "null",后者抛空指针;
  2. Integer.valueOf(100) == Integer.valueOf(100) 的结果:true(缓存命中);
  3. 为什么推荐BigDecimal.valueOf(0.1) 而非 new BigDecimal(0.1):避免浮点数精度丢失。

5.字符串的大小写转换

java 复制代码
String str = "hello"; 
String str1 = "HELLO"; 

str = str.toUpperCase();// HELLO  小写转大写
str1 = str1.toLowerCase();// hello 大写转小写

6.字符串和字符数组的转换

java 复制代码
String str = "hello";
char[] ch = str.toCharArray();

for(char ch1 : ch){
    System.out.print(ch1 + " "); // h e l l o
}
System.out.println();

String str1 = new String(ch);
System.out.println(str1.toString()); //hello

7.字符串替换

java 复制代码
String str = "hello";
str = str.replace('h','b');
System.out.println(str.toString()); //bello

str = str.replace("ll","s");
System.out.println(str.toString()); //heso

replace是String类的内置方法.

replaceFirst()方法是只替换第一个

replaceAll()方法是全部都替换

8.字符串拆分

java 复制代码
String str = " I_am_a_teacher";
String[] str1 = str.split("_");
System.out.println(str.toString()); // I_am_a_teacher
for(String s : str1){
    System.out.print(s.toString() + " "); // I am a teacher 
}

按照_来拆分字符串,返回的是一个String[]数组。

9.字符串的截取

java 复制代码
String str = "helloworld";
str = str.substring(2);
System.out.println(str.toString());// lloworld
str = str.substring(2,4);
System.out.println(str.toString());// ow

将字符串的前两个进行截取掉。也可以是两个参数,一般是左闭右开的区间

10.删除字符串首尾的空格

java 复制代码
String str = "    hello    world    ";
str = str.trim();
System.out.println(str.toString()); //hello    world

11.字符串的不可变性

  1. String类在设计的时候就是不可以被修改的,所有涉及到可能修改String内容的都是重新创建新对象,对新对象进行修改。
  2. 被final修饰的类声明该类不可以被继承,final修饰引用类型表明了该引用变量不能再引用其他对象,但是其引用对象的内容可以修改。

12.StringBuilder和StringBuffer

逆制字符串:StringBuilder.reverse();

  1. String不可以被修改,但是StringBuilder和StringBuffer可以被修改。
  2. 但是StringBuilder一般是在单线程下,StringBuffer一般是在多线程下,可以保证线程安全。
  3. StringBuilder和StringBuffer的方法大多相同.
相关推荐
conkl1 小时前
Python中的鸭子类型:理解动态类型的力量
开发语言·python·动态·鸭子类型·动态类型规划
小小8程序员1 小时前
swift的inout的用法
开发语言·ios·swift
.柒宇.1 小时前
力扣hot100---42.接雨水(java版)
java·算法·leetcode
D***44141 小时前
Spring Boot 多数据源解决方案:dynamic-datasource-spring-boot-starter 的奥秘(上)
java·spring boot·后端
youngee111 小时前
hot100-41验证二叉搜索树
算法
迈巴赫车主1 小时前
蓝桥杯20534爆破 java
java·数据结构·算法·职场和发展·蓝桥杯
祈澈菇凉1 小时前
Next.js 零基础开发博客后台管理系统教程(一):环境搭建与项目初始化
开发语言·javascript·ecmascript
汝生淮南吾在北1 小时前
SpringBoot+Vue在线笔记管理系统
java·vue.js·spring boot·笔记·毕业设计·毕设
wjs20241 小时前
Go 语言切片(Slice)
开发语言