本文主要是介绍Java 字符串 String、StringBulider和StringBuffer,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
文章目录
- 一、可变和不可变对象
- 1、String
- 2、StringBuffer和StringBuilder
- 二、不可变对象的好处
一、可变和不可变对象
可变对象:当您拥有对对象实例的引用时,该实例的内容可以更改
不可变对象:当您拥有对对象实例的引用时,该实例的内容无法更改
使用java.lang.String作为不可变类,使用java.awt.Point作为可变类
public class StringTest {public static void main(String[] args) {Point myPoint = new Point( 0, 0 );System.out.println( myPoint );myPoint.setLocation( 1.0, 0.0 );System.out.println( myPoint );String myString = new String( "old String" );System.out.println( myString );myString.replaceAll( "old", "new" );System.out.println( myString );}
}
结果输出如下
java.awt.Point[x=0,y=0]
java.awt.Point[x=1,y=0]
old String
old String
我们只查看每个对象的单个实例,但是可以看到myPoint的内容发生了变化,而myString的内容没有发生变化。
某些语言,例如 C++ 和Ruby,通常允许在创建字符串后更改其内容;这些被称为可变字符串。在其他语言中,例如Java和Python,该值是固定的,如果要进行任何更改,则必须创建一个新字符串;这些被称为不可变字符串(其中一些语言还提供了另一种可变类型,例如 Java 和.NET StringBuilder、线程安全的 JavaStringBuffer和Cocoa NSMutableString)。
1、String
在 Java 编程中广泛使用的字符串是一个字符序列。在 Java 编程语言中,字符串是对象。
通过查看String.java的源码可以知道String是被final修饰的,因此它是不能被继承的。
public final class String {
}
下面我们来看一组代码
public class StringTest {public static void main(String[] args) {String str1 = "hello";String str2 = "hello";System.out.println(str1 == str2);}
}
下面是该代码的内存图
凡是带有双引号的字符串都会放在字符串常量池中,字符串放在字符串常量池是为了提高效率。如果使用构造函数或方法创建字符串,则这些字符串将存储在堆内存中的SringConstantPool,但是在保存到池中之前,它会调用intern()
方法来使用 equals()
方法检查池中具有相同内容的对象可用性。如果池中的字符串副本可用,则返回引用。否则,将 String 对象添加到池中并返回引用。
再来看一组代码
public class StringTest {public static void main(String[] args) {String str3 = new String("abcde");String str4 = new String("abcde");System.out.println(str3 == str4);}
}
此时 str3 和 str4 都在堆中创建了对象,这两个对象时两个不同地址的空间,所以上述代码的结果为false。但是他们所指引的字符串还是在字符串常量区中。
下面我们再来看一组代码,以下代码会创建十一个对象。假如,我们for循环执行上万条,此时,会造成字符串常量区溢出,所以这个时候就不适合在循环里使用连接符操作字符串。这时就出现了StringBuff
和StringBuilder
String str = "a";
for (int i = 0; i < 10; i++) {str += "b";
}
System.out.println(str);
2、StringBuffer和StringBuilder
String
是一个不可变的类,无法改变。StringBuilder
是一个可变类,可以附加到替换或删除的字符,最终转换为String
。
下面是常用的方法
public class StringTest {public static void main(String[] args) {StringBuilder sb = new StringBuilder();String str = "java";// 将字符串添加"xiao"字符串sb.append("xiao");// 将sb字符串中第 [0, 2) 位字符替换为str -- javaaosb.replace(0, 2, str);// 删除第 [3, 5) 为字符 -- javosb.delete(3, 5);// 返回字符串的长度 -- 4System.out.println(sb.length());// 返回指定下标的值 -- jSystem.out.println(sb.charAt(0));// 返回下标为 [0, 3) 之间的子序列 -- javSystem.out.println(sb.substring(0, 3));System.out.println(sb);}
}
StringBuffer 每当我们对使用此类创建的任何 String 进行一些更改时,都不会创建新对象,因为更改是在同一对象中进行的。这个类是线程安全的,即它可以在多线程环境中正常工作。此类的方法是同步的,因此每当多个线程调用对象上的某些方法时,它们就会按照每个单独线程进行的方法调用的顺序执行。
常用方法:
- append – 在字符串的末尾追加数据。
- insert – 在任何给定索引处插入数据。
StringBuilder 这是 StringBuffer
类的一个新的但更小的版本,随着 JDK 5 的发布而引入。它与 StringBuffer
类似,但它不为线程安全或同步提供任何保证。
它用于只有一个线程应用程序的地方,因为它在大多数情况下要快得多。其余部分与 StringBuffer
类似,具有相同的方法和声明。我们只需要在初始化期间使用不同的类,其余的代码不需要更改,因为它也有相同的方法。
下面是三者的区别
二、不可变对象的好处
- 默认情况下,不可变对象是线程安全的,可以在并发环境中共享而无需同步。
- 不可变对象简化了开发,因为它更容易在多个线程之间共享,而无需外部同步。
-通过减少代码中的同步,java应用程序的不可变对象提升性能。 - 不可变对象的另一个重要优点是可重用性,您可以缓存不可变对象并重用它们,就像字符串文本和整数一样。您可以使用静态工厂方法来提供valueOf()之类的方法,它可以从缓存返回现有的不可变对象,而不是创建新对象。
来看下他们三个的使用场景
-
如果不是在循环体中进行字符串拼接的话,直接使用 String 的 “+” 就好了。
-
单线程循环中操作大量字符串数据 → StringBuilder.append()
-
多线程循环中操作大量字符串数据 → StringBuffer.append()
这篇关于Java 字符串 String、StringBulider和StringBuffer的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!