Java中的String、StringBuilder、StringBuffer

1. 继承关系图

这里写图片描述

当使用文本数据时,Java提供了三种类别,包括String, StringBuffer和StringBuilder。当使用大数据来工作时,你应该用StringBuffer或StringBuilder来优化效率。基本上这三个类有许多相似之处。

  • String 是不可变的(这个概念的更多详细信息,在文档中)。它不允许子类的存在。
  • StringBuffer, StringBuilder 是可变的。

StringBuilder和StringBuffer都是一样的,除了涉及到多线程的使用情况。

  • 为了处理多线程使用文本,你应该为了防止线程之间冲突而使用StringBuffer。
  • 要使用一个线程处理的文本,你应该使用StringBuilder。

至于处理的速度,StringBuilder是最好的,其次是StringBuffer,而最后是String。

2. String类型

String 在Java中是最重要的一个类,Java编程开始使用字符串就使用著名的System.out.println()语句在控制台上打印东西。许多Java初学者不知道String是不可变的和最终的Java字符串结果,每次修改需要创建一个新的String对象。

2.1- String是一个非常特殊的类

字符串接受Java的特殊处理,因为它们在程序中经常使用。因此,效率(在计算和存储方面)是至关重要的。
Java的设计者决定这一个面向对象语言,以保留原始类型,而不是使所有的对象, 以便提高语言的性能。原始数据存储(在)调用栈,其需要较少的存储空间和更方便的操作。另一方面,对象被存储在程序堆,这需要复杂的存储器管理和更多的存储空间。出于性能的原因,Java字符串被设计为在一种原始和类之间类型。特殊功能的字符串包括:

  1. “+”操作符,它执行的加入对原始类型(如int和double),重载对String对象进行操作。’+’两个字符串操作数进行串联。 Java不考虑让开发者支持运算符重载。在支持运算符重载像C++语言,可以把一个“+”操作符来执行减法,引起不良代码。 “+”操作符是重载的内部支持字符串连接在Java中的唯一操作符。注意到,“+”不在两个任意对象上工作。

  2. 一个字符串,可以通过构造:
    直接分配字符串到字符串引用 - 就像一个原始数据类型或通过“new”操作符和构造,类似于任何其他类。然而,这是不常用的,所以不推荐。

  3. 字符串字面存储在一个公共池。这有利于对具有相同内容的字符串,以节省存储存储的共享。new操作符分配的String对象都存储在堆中,并没有对相同内容的共享存储。

2.2 String文字和String对象

正如前面提到的,有两种方法来构造字符串:通过指定一个字符串字面量或显式创建通过 new 操作符,并构造一个String对象的隐式构建。 例如,

String s1 = "Hello";              // String literal
String s2 = "Hello";              // String literal
String s3 = s1;                   // same reference
String s4 = new String("Hello");  // String object
String s5 = new String("Hello");  // String object

我们使用以下图片说明来解释它:

这里写图片描述

Java已经提供了一个特殊的机制,来保存字符串文字 - 所谓的字符串公共池。如果两个字符串具有相同的内容,它们将共享公共池内同一存储器。这样的做法是采取以节省对经常使用的字符串存储。在另一方面,通过 new 操作符和构造器创建String对象都保存在堆中。 在堆中的每个String对象都有自己的存储就像任何其他对象。没有共享存储堆,即使两个String对象具有相同的内容。
可以使用String类的方法equals()方法比较两个字符串的内容。可以使用关系等于运算符’==’来比较两个对象的引用(或指针)。研究以下代码:

String s1 = "Hello";              // String literal
String s2 = "Hello";              // String literal
String s3 = s1;                   // same reference
String s4 = new String("Hello");  // String object
String s5 = new String("Hello");  // String object

s1 == s1;         // true, same pointer
s1 == s2;         // true, s1 and s2 share storage in common pool
s1 == s3;         // true, s3 is assigned same pointer as s1
s1 == s4;         // false, different pointers
s4 == s5;         // false, different pointers in heap

s1.equals(s3);    // true, same contents
s1.equals(s4);    // true, same contents
s4.equals(s5);    // true, same contents

事实上,你应该使用字符串,而是采用了“new”的操作符,这有助于加快程序运行速度。

3. StringBuffer 和 StringBuilder

StringBuffer是可变的。它可以在长度和内容方面发生变化。StringBuffer是线程安全的,这意味着它们已经同步方法来控制访问,以便只有一个线程可以在同一时间访问一个StringBuffer对象同步代码。因此,StringBuffer的对象通常在多线程环境中是安全的,使用多个线程可以试图同时访问相同StringBuffer对象。

StringBuilder类非常相似的StringBuffer,不同之处在于它的访问不同步的,因此,它不是线程安全的。由于不同步,StringBuilder的性能可以比StringBuffer更好。因此,如果在单线程环境中工作,使用StringBuilder,而不是StringBuffer可能会有更高的性能。这也类似其他情况,如StringBuilder的局部变量(即一个方法中的一个变量),其中只有一个线程会访问一个StringBuilder对象。

StringBuffer的方法(StringBuilder相似)
// Constructors
StringBuffer()             // an initially-empty StringBuffer
StringBuffer(int size)     // with the specified initial size
StringBuffer(String s)     // with the specified initial content

// Length
int length()

// Methods for building up the content
// type could be primitives, char[], String, StringBuffer, etc
StringBuffer append(type arg)  // ==> note above!
StringBuffer insert(int offset, type arg) // ==> note above!

// Methods for manipulating the content
StringBuffer delete(int start, int end)
StringBuffer deleteCharAt(int index)
void setLength(int newSize)
void setCharAt(int index, char newChar)
StringBuffer replace(int start, int end, String s)
StringBuffer reverse()

// Methods for extracting whole/part of the content
char charAt(int index)
String substring(int start)
String substring(int start, int end)
String toString()

// Methods for searching
int indexOf(String searchKey)
int indexOf(String searchKey, int fromIndex)
int lastIndexOf(String searchKey)
int lastIndexOf(String searchKey, int fromIndex)

这里写图片描述

  • StringBuilderDemo.java

package com.yiibai.tutorial.strbb;

public class StringBuilderDemo {

public static void main(String[] args) {

    // Create StringBuilder object
    // with no characters in it and
    // an initial capacity specified by the capacity argument
    StringBuilder sb = new StringBuilder(10);

    // Append the string Hello ... on sb.
    sb.append("Hello...");
    System.out.println("- sb after appends a string: " + sb);

    // append a character
    char c = '!';
    sb.append(c);
    System.out.println("- sb after appending a char: " + sb);

    // Insert a string at index 5
    sb.insert(8, " Java");
    System.out.println("- sb after insert string: " + sb);


    // Delete substring at index 5 to 8
    sb.delete(5,8);

    System.out.println("- sb after delete: " + sb);
}

}

运行示例的结果:

- sb after appends a string: Hello...
- sb after appending a char: Hello...!
- sb after insert string: Hello... Java!
- sb after delete: Hello Java!
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值