欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 文化 > Java字符串

Java字符串

2025/6/18 17:22:27 来源:https://blog.csdn.net/m0_70296476/article/details/147233928  浏览:    关键词:Java字符串

目录

一、String类

1. 概述

2. 创建方式

(1)直接赋值

(2)使用new关键字

3. 性能优化

4. 常用方法

(1)==

(2)equals()

(3)concat()

二、StringBuilder类

1. 概述

2. 核心特性

3. 常用方法

(1)append

(2)insert

(3)delete

(4)reverse

(5)toString

4. 性能优化技巧

(1)预设容量(Pre-sizing)

(2)链式调用优化(Method Chaining)

(3)避免循环内重复创建

(4)批量操作替代单个操作

三、StringBuffer类

1. 概述

2. 核心特性

3. 适用场景

四、StringJoiner类

1. 概述

2. 核心特性

3. 基本构造方式

4. 常用方法

(1)add

(2)merge

(3)toString

五、字符串拼接的底层原理

1. 使用+操作符拼接

(1)没有变量(纯字面量拼接)

(2)有变量(涉及变量拼接)

2. 使用String.concat()方法

3. 使用StringBuilder或StringBuffer


Java中的字符串处理类包括StringStringBuilderStringBufferStringJoiner等,它们各自有不同的特性和底层实现原理。

一、String

1. 概述

String类位于java.lang包中,是Java中最基础的字符串类,其底层是一个被final修饰的字符数组char[] value( JDK9及之后,为了节省内存空间,改为使用byte[]数组存储字符 ),这意味着一旦创建,其内容不可更改。这种不可变性使得String在多线程环境下是安全的,但同时也带来了性能开销,因为每次修改都需要创建新的对象。

2. 创建方式

(1)直接赋值

比如 String s = "abc"; 。当使用双引号直接赋值时,系统会检查该字符串在串池中是否存在,如果不存在就创建新的字符串,如果存在就复用。

(2)使用new关键字

比如 String s = new String("abc"); 。这种方式会创建新的字符串对象,每new一次就会在堆内存里开辟一块新的空间并创建新的对象,占用额外的内存。

常用构造方法

  • String():创建一个空字符串。

  • String(String original):根据传入的字符串创建一个新的字符串对象。

  • String(char[] value):根据字符数组创建一个新的字符串对象。

 public static void main(String[] args) {char[] chars = {'a', 'b', 'c', 'd'};String s = new String(chars);System.out.println(s);  // abcd}
  • String(byte[] bytes, Charset charset):根据字节数组和指定的字符集创建一个新的字符串对象。

 public static void main(String[] args) {byte[] bytes = {97, 98, 99, 100};String s = new String(bytes);System.out.println(s);  // abcd}

3. 性能优化

  • 使用字符串常量池避免重复创建相同字符串。

  • 避免频繁修改字符串,因为每次修改都会导致新对象的创建。

4. 常用方法

(1)==

如果是基本数据类型, == 比较的是数据值;如果是引用数据类型, == 比较的是地址值。字符串是引用数据类型,所以比较的是地址值。

 public static void main(String[] args) {String s1 = new String("abc");  // s1记录的是堆里面的地址值String s2 = "abc";  // s2记录的是串池中的地址值System.out.println(s1 == s2);  // false}
(2)equals()

equals() 比较的是字符串内容。如果要忽略大小写的比较,可以使用 equalsIgnoreCase()

 public static void main(String[] args) {String s1 = new String("abc");String s2 = "abc";System.out.println(s1.equals(s2));  // true}
(3)concat()

concat() 方法会创建一个新的字符串对象,效率较低。

二、StringBuilder

1. 概述

StringBuilder是可变字符串类(可以看作一个容器),其底层同样是一个字符数组(char[] value),但与String不同的是,它允许动态修改内容,因此比String更高效。

2. 核心特性

  1. 可变性(Mutable) :内容可被修改而不产生新对象。

  2. 非线程安全(Not Thread-Safe) :比线程安全的StringBuffer性能更高。

  3. 动态扩容(Dynamic Expansion) :自动增加内部缓冲区容量。

  4. 高效操作(Efficient Operations) :避免频繁内存分配。

3. 常用方法

(1)append
 StringBuilder sb = new StringBuilder("abc");​// 基本类型追加(自动转换为字符串)sb.append(def)sb.append(123)sb.append(2.5)sb.append(true)​// 对象追加(调用toString())sb.append(Object obj)​// 子串追加(支持偏移量)sb.append(char[] str, int offset, int len)sb.append(CharSequence s, int start, int end)
(2)insert
 sb.insert(int offset, boolean b)sb.insert(int offset, char c)sb.insert(int offset, int i)sb.insert(int offset, Object obj)
(3)delete
 sb.delete(int start, int end)  // 删除[start,end)区间内容  sb.deleteCharAt(int index)  // 删除指定位置字符  
(4)reverse
 sb.reverse()  // 原地反转字符序列  
(5)toString
 String str = sb.toString();  // 转换为不可变字符串

4. 性能优化技巧

(1)预设容量(Pre-sizing)
 // 预估最终长度设置初始容量  StringBuilder sb=new StringBuilder(1024); 
(2)链式调用优化(Method Chaining)
 sb.append("a").append("b").append("c").reverse().toString();
(3)避免循环内重复创建
 // 错误示范(每次循环都新建)for(...){ sb=new StringBuilder(); }​// 正确做法(复用同一个)StringBuilder sb=new StringBuilder();for(...){ sb.setLength(0); }
(4)批量操作替代单个操作
 // 低效方式  for(char c:chars){ sb.append(c); }​// 高效方式  sb.append(chars);

三、StringBuffer

1. 概述

StringBufferStringBuilder 非常相似,但是其特点是线程安全。因为其方法被 synchronized 修饰,这使得它适用于多线程环境,但因此带来了性能开销。

2. 核心特性

  • 线程安全(Thread-Safe) :所有公开方法都使用 synchronized

  • 可变性(Mutable) :内容可被修改而不产生新对象。

  • 动态扩容(Dynamic Expansion) :自动增加内部缓冲区容量。

  • 兼容性(Compatibility) :从Java1.0开始就存在。

3. 适用场景

适用于多线程环境下需要修改字符串的场景。在多线程环境下使用时,可以避免锁竞争问题,但在单线程环境下不如StringBuilder高效。

四、StringJoiner

1. 概述

StringJoiner 是Java8引入的一个专门用于构造由分隔符分隔的字符序列的工具类,它简化了集合元素连接、CSV格式生成等常见场景下的字符串拼接操作。

2. 核心特性

  • 分隔符控制(Delimiter) :可指定固定分隔符连接元素。

  • 前后缀支持(Prefix/Suffix) :可为结果添加统一的前后缀。

  • 空值处理(Null Handling) :提供灵活的空元素处理策略。

  • 链式调用(Fluent API) :支持方法链式调用风格。

3. 基本构造方式

 // 仅指定分隔符(无前后缀)new StringJoiner(",")​// 完整构造(带前后缀)new StringJoiner(",", "[", "]")

4. 常用方法

(1)add
 StringJoiner sj = new StringJoiner(",");​// 添加单个元素(支持任意CharSequence)sj.add("A").add("B").add("C");​// 添加多个元素的快捷方式(Java8+)List<String> list = Arrays.asList("X","Y","Z");list.forEach(joiner::add);
(2)merge
 // 合并另一个StringJoiner的内容(忽略其前后缀)StringJoiner sj1 = new StringJoiner(",", "[", "]");StringJoiner sj2 = new StringJoiner(",", "[", "]");sj1.add("A").add("B");sj2.add("X").add("Y");sj1.merge(sj2);System.out.println(sj1);  // 输出:[A,B,X,Y]
(3)toString
 String str = sj1.toString();System.out.println(str);  // 输出:[A,B,X,Y]

五、字符串拼接的底层原理

1. 使用+操作符拼接

(1)没有变量(纯字面量拼接)

当拼接的内容全部是字符串字面量时,Java编译器会在编译阶段直接将其优化为一个常量字符串,优化后的字符串会被存储在字符串常量池中,避免运行时创建额外的对象。

 String result = "Hello" + "World";// 上述代码会被编译器优化为:String result = "HelloWorld";

性能特点

  • 高效:由于编译期优化,运行时无需创建StringBuilder对象,性能最佳。

  • 内存节省:字符串直接存储在常量池中,减少内存开销。

(2)有变量(涉及变量拼接)

当拼接的内容包括变量时:JDK8以前,系统底层会创建一个StringBuilder对象,依次调用append()方法将每个字符串片段添加到StringBuilder对象中,然后调用toString()方法将StringBuilder对象转换为String对象,而toString()方法的底层是直接new了一个字符串对象。JDK8及以后,系统会预估字符串拼接之后的总大小,把要拼接的内容都放在数组里,本质上也是产生了一个新的字符串。

 String str1 = "Hello";String str2 = "World";String result = str1 + str2;// 上述代码会被编译器转换为:String str1 = "Hello";String str2 = "World";String result = new StringBuilder().append(str1).append(str2).toString();

性能特点

  • 运行时开销:每次拼接都会创建StringBuilder对象,增加运行时开销。

  • 内存开销:生成的字符串存储在堆内存中,而不是常量池中。

2. 使用String.concat()方法

String.concat()方法用于将指定字符串连接到此字符串的末尾。它实际上是通过创建一个新的字符数组,将两个字符串的内容复制到新数组中,然后构造一个新的String对象。

性能特点

  • concat()方法每次调用都会创建一个新的String对象,因此在频繁拼接字符串时性能较差,适用于少量字符串的拼接。

3. 使用StringBuilder或StringBuffer

StringBuilder和StringBuffer都提供了可变的字符序列,允许对字符串内容进行修改而不需要创建新的对象。执行流程:创建一个StringBuilder或StringBuffer对象,调用append()方法将每个字符串片段添加到对象中,调用toString()方法将对象转换为String对象。

性能特点

  • StringBuilder是非线程安全的,但性能较高。StringBuffer是线程安全的,但性能稍低(因为添加了同步机制)。

  • 在需要频繁拼接字符串的场景中,使用StringBuilder或StringBuffer可以显著提高性能。

  • StringBuilder适用于单线程环境,而StringBuffer适用于多线程环境。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词