如何使用字符串stringbuilder和stringbuffer

时间:2019-04-29 03:17:56  来源:igfitidea点击:

在任何编程语言中,变量使用最多的数据类型是布尔值、数字基元类型值和字符的"字符串"(或数组)。与 C 或 C++相比,Java 处理字符串是不同的,因为:

  • 在 Java 中,每个字符都是一个 16 位 Unicode 值,而不是 1 字节;
  • 在 Java 中,字符串值由 String 对象管理;
  • 在 Java 中,语法允许我们使用 Strings 作为基元数据类型(我们可以使用 + 运算符初始化它们)
  • 在 Java 中,字符串是不可变的对象,这意味着一旦创建,它们就无法更改其值。

如何定义和初始化字符串

由于字符串值由 String 对象管理,因此可以使用默认语法创建它:

String s = new String();

      String sWithValue = new String("Hello String !");

正如之前所说的,由于字符串是使用最多的数据类型之一,Java 语法允许我们把它们当做基元数据类型来使用,可以使用=运算符:

String s = "Hello String !";

      s = "Hello Java !";

在2 个字符串引用之间 使用等号=时,不要忘记 Java 字符串是对象。我们将复制引用值而不是对象值。

String string1 = "Hello String !";

      String string2 = string1;

      if(string1 == string2)

          System.out.println("相等");

      else

          System.out.println("不相等);

将打印"相等",因为引用具有相同的值/地址,并在内存中生成这种情况:

java-scjp-10-how-to-use-string-stringbuilder-and-stringbuffer

什么是字符串是不可变的

不可变对象是一旦创建它,它无法更改其值的对象。
字符串是不可变的,基于前面的示例,让我们看看当我们执行类似操作时会发生什么:

String string1 = "Hello String !";;

      System.out.println(string1);

      string1 = "Hello !";

      System.out.println(string1);

如果运行此示例,则结果是:

Hello String !

Hello !

第一印象是 string1 变量将其值从"Hello String!" 更改为"Hello!"

但这是错的,因为 字符串是不可变的
string1 是字符串引用,而不是对象;

因此,实际上是,第二个语句生成一个新的 String 对象,并且 [string1] 引用获取新对象的地址,如此变成:

java-scjp-10-how-to-use-string-stringbuilder-and-stringbuffer

什么是字符串常量池

在 Java 中,String 对象非常特殊(因为它们是不可变的),因为它们的值以特殊方式处理。为了有效地使用内存,JVM 通过将字符串值(尤其是字符串文本字面量)放在称为"字符串常量池"的特殊内存区域来管理字符串值(尤其是字符串文本字面量)。使用文本字面量值来初始化字符串时,JVM 会检查池以查看 String的值是否已在内存中。如果是,JVM将不会创建新值,JVM将把String的地址放在引用中。

基于此规则,下面这个示例将打印 “相等”

流程数据如下所示:

String string3 = "Hello String !";

String string4 = "Hello String !";

if(string3 == string4)    // 比较字符串引用,而不是值

    System.out.println("“相等”");

else

    System.out.println("不相等");

java-scjp-10-how-to-use-string-stringbuilder-and-stringbuffer

字符串常量池

(1) 在字符串常量池中设置值"Hello String !
(2) String4 引用指向池中的现有字符串

使用new创建字符串和使用 =运算符创建字符串比较

如我们所看到的,有两种方法可以创建 String 对象:

使用newString s1 = new String(“Hello !”);
使用 等号=运算符String s2 = “Hello !”;

两者的区别是:

当我们使用 new 时,String 对象的行为类似于一个普通对象,这意味着其值被放置在堆中,而不是放在称为 String 常量池的特殊区域中。

因为,String 类是一个特殊的类,你不能继承它并重写它的功能。字符串类String是被标记为final的。

如何处理字符串

String 类有很多用于处理该值的方法。使用最多的是:

方法说明
charAt()返回给定索引的字符;索引将值从 0 到 length()-1;
concat()将字符串追加到另一个字符串的末尾; 和加号+作用一样。
equals()比较两个字符串值(通过字符值比较)
length()返回字符数;它不是数组的长度属性。这是一种方法
replace()替换字符
substring()返回子字符串
toLowerCase()将所有字符转换为小写
toString()返回 String 对象的值
toUpperCase()将所有字符转换为大写
trim()删除字符串首尾的空白字符

由于 String 是不可变的,因此在使用其中一些函数时必须注意,因为它们的结果是一个新的 String 对象。 这些方法不会影响当前对象。

什么是字符串构建器(StringBuilder)和字符串缓冲区(StringBuffer)

这两个类几乎相同(它们具有相同的 API)。它们之间的区别在于 StringBuilder(从 Java 5 添加)不是线程安全的,而且速度更快。

定义这两个类是因为它们以更高效的方式(内存)处理字符串值。原因之一是它们的值不存储在字符串常量池中,它们的行为与普通对象一样 - 当对象不是引用被 GC 销毁并且不会保留在字符串常量池中时。

StringBuilder 和 StringBuffer 背后的理念是提供具有大型流的高效 I/O 操作方法。

StringBuilder 和 StringBuffer 实例仅使用新运算符创建,而不是使用字符串:

如果要修改 StringBuilder 或 StringBuffer 的值,可以使用这些类中的方法。大多数使用的方法有:

方法说明
append()将参数添加到当前对象的末尾
delete()删除开始索引和结束索引之间的字符
insert()在给定的offset位置插入值
reverse()反转当前对象的值
toString()返回StringBuilder 或者 StringBuffer 对象的值object

[这些方法影响调用对象的值] 比如:

StringBuilder sb1 = new StringBuilder("12345");

sb1.append("6789");

System.out.println(sb1);    //打印 123456789

sb1.delete(0,2);

System.out.println(sb1);    //打印 3456789

sb1.reverse();

System.out.println(sb1);    //打印 9876543

关于 StringBuilder 或 StringBuffer 的另一个事实是,我们可以调用多个方法 - 在同一对象上的链式方法。请记住,链式方法会影响调用对象,并且它们从左到右执行。

链式操作:

StringBuilder sb2 = new StringBuilder("Test");

sb2.append(" Java ").delete(0, 4).insert(0,"Begin");

System.out.println(sb2);    //打印 Begin Java

输出结果: Begin Java