“CharBuffer、CharSequence、String、StringBuilder、StringBuffer”的版本间差异
跳到导航
跳到搜索
无编辑摘要 |
(→String) |
||
(未显示同一用户的7个中间版本) | |||
第1行: | 第1行: | ||
[[category:Java]] | [[category:Java]] | ||
== 关于 == | |||
在Java中,字符存储相关的类有 String, StringBuffer, StringBuilder, CharBuffer, CharSequence以及可以存储原始数据的 ByteBuffer。 | |||
* “'''CharSequence'''”:('''接口'''),表示 char 值的一个可读序列,是所有String相关的接口; | |||
**(此接口对许多不同种类的 char 序列提供统一的只读访问) | |||
**(“CharBuffer”、“Segment”、“String”、“StringBuffer”、“StringBuilder”,都实现了“CharSequence”接口) | |||
* “'''String'''”:'''不可变'''字符串类,最方便,效率低; | |||
* “'''StringBuffer'''”:'''线程安全'''的字符串缓冲,比String功能差,但是快; | |||
* “'''StringBuilder'''”:'''线程不安全'''的字符串缓冲,与StringBuffer功能相同,但是'''比StringBuffer更快'''; | |||
PS: | |||
* “'''ByteBuffer'''”:('''抽象类''',“'''java.nio'''”包中)字节缓冲,'''没有字符集'''; | |||
* “'''CharBuffer'''”:('''抽象类''',“'''java.nio'''”包中)字符缓冲,'''没有字符串操作功能'''; | |||
== 基础接口/抽象类 == | |||
=== CharSequence === | |||
接口,表示char值的一个可读序列。此接口'''对不同种类的char序列提供统一的只读访问接口'''。 | |||
* 此接口不修改equals和hashCode方法; | |||
* 实现类:“CharBuffer”、“String”、“StringBuilder”、“StringBuffer”; | |||
<syntaxhighlight lang="java"> | |||
package java.lang; | |||
import . . .; | |||
public interface CharSequence { | |||
// 返回指定索引的 char 值 | |||
int length(); | |||
// 返回此字符序列的长度 | |||
char charAt(int index); | |||
// 返回一个新的 CharSequence,它是此序列的子序列 | |||
CharSequence subSequence(int start, int end); | |||
// 返回一个包含此序列中字符的字符串,该字符串与此序列的顺序相同 | |||
public String toString(); | |||
public default IntStream chars() { | |||
. . . | |||
} | |||
public default IntStream codePoints() { | |||
. . . | |||
} | |||
} | |||
</syntaxhighlight> | |||
=== Appendable === | |||
接口,表示可添加char序列和值。 | |||
* 实现类:“CharBuffer”、“StringBuffer”、“StringBuilder”、“BufferedWriter”、“CharArrayWriter”、“FileWriter”等; | |||
<syntaxhighlight lang="java"> | |||
package java.lang; | |||
import java.io.IOException; | |||
public interface Appendable { | |||
Appendable append(CharSequence csq) throws IOException; | |||
Appendable append(CharSequence csq, int start, int end) throws IOException; | |||
Appendable append(char c) throws IOException; | |||
} | |||
</syntaxhighlight> | |||
=== AbstractStringBuilder === | |||
抽象类,表示可变的字符序列。 | |||
* 实现了“CharSequence”和“Appenable”接口; | |||
<syntaxhighlight lang="java"> | |||
package java.lang; | |||
import sun.misc.FloatingDecimal; | |||
import java.util.Arrays; | |||
abstract class AbstractStringBuilder implements Appendable, CharSequence { | |||
char[] value; | |||
int count; | |||
. . . | |||
@Override | |||
public abstract String toString(); | |||
final char[] getValue() { | |||
return value; | |||
} | |||
</syntaxhighlight> | |||
== 实用类 == | |||
=== String === | |||
* 接口实现: | |||
*# 实现了“CharSequence”接口,为可访问的char序列; | |||
*# 实现了“Serializable”接口,可以被序列化。 | |||
*# 实现了“Comparable<String>”,支持String之间的相互比较。 | |||
* 数据结构:字符数组“char[]”,存储字符的unicode值。 | |||
* '''不可变''':一旦生成,char[]中数据就不可变。即String内容不变。 | |||
* '''重复利用''':当新创建“String test = "abc"”时,JVM会到String常量池查询是否已经存在内容为“abc”的String对象: | |||
*# 如果已经存在该String,则把test设置为这个对象的引用; | |||
*# 如果不存在,则新创建一个内容为“abc”的String对象,并加入常量池。 | |||
<syntaxhighlight lang="java"> | |||
package java.lang; | |||
import . . .; | |||
public final class String | |||
implements java.io.Serializable, Comparable<String>, CharSequence { | |||
private final char value[]; | |||
private int hash; // Default to 0 | |||
private static final long serialVersionUID = -6849794470754667710L; | |||
private static final ObjectStreamField[] serialPersistentFields = | |||
new ObjectStreamField[0]; | |||
. . . | |||
public native String intern(); | |||
} | |||
</syntaxhighlight> | |||
*(关于“intern”方法,见“[http://wiki.eijux.com/%E6%B7%B1%E5%85%A5%E7%90%86%E8%A7%A3JVM%EF%BC%9AJava%E5%86%85%E5%AD%98%E5%8C%BA%E5%9F%9F%E4%B8%8E%E5%86%85%E5%AD%98%E6%BA%A2%E5%87%BA%E5%BC%82%E5%B8%B8#.E5.85.B3.E4.BA.8EString.intern.28.29 关于String.intern()]”) | |||
=== StringBuffer === | |||
* 继承自“AbstractStringBuilder”,实现了“Serializable”、“CharSequence”接口; | |||
* 数据结构:使用父类“AbstractStringBuilder”中的字符数组; | |||
* '''线程安全:所有的“public”方法都添加了“synchronized”同步锁'''; | |||
* '''仅在“toString()”时生成String对象,且在不修改内容的情况下只生成一次'''; | |||
<syntaxhighlight lang="java"> | |||
package java.lang; | |||
import java.util.Arrays; | |||
public final class StringBuffer | |||
extends AbstractStringBuilder | |||
implements java.io.Serializable, CharSequence | |||
{ | |||
private transient char[] toStringCache; | |||
static final long serialVersionUID = 3388685877147921107L; | |||
public StringBuffer() { | |||
super(16); | |||
} | |||
public StringBuffer(int capacity) { | |||
super(capacity); | |||
} | |||
public StringBuffer(String str) { | |||
super(str.length() + 16); | |||
append(str); | |||
} | |||
public StringBuffer(CharSequence seq) { | |||
this(seq.length() + 16); | |||
append(seq); | |||
} | |||
. . . | |||
@Override | |||
public synchronized String toString() { | |||
if (toStringCache == null) { | |||
toStringCache = Arrays.copyOfRange(value, 0, count); | |||
} | |||
return new String(toStringCache, true); | |||
} | |||
</syntaxhighlight> | |||
=== StringBuilder === | |||
* 继承自“AbstractStringBuilder”,实现了“Serializable”、“CharSequence”接口; | |||
* 数据结构:使用父类“AbstractStringBuilder”中的字符数组; | |||
* '''可变'''; | |||
* '''非线程安全'''; | |||
* '''仅在“toString()”时生成String对象'''; | |||
<syntaxhighlight lang="java"> | |||
package java.lang; | |||
public final class StringBuilder | |||
extends AbstractStringBuilder | |||
implements java.io.Serializable, CharSequence | |||
{ | |||
static final long serialVersionUID = 4383685877147921099L; | |||
public StringBuilder() { | |||
super(16); | |||
} | |||
public StringBuilder(int capacity) { | |||
super(capacity); | |||
} | |||
public StringBuilder(String str) { | |||
super(str.length() + 16); | |||
append(str); | |||
} | |||
public StringBuilder(CharSequence seq) { | |||
this(seq.length() + 16); | |||
append(seq); | |||
} | |||
. . . | |||
@Override | |||
public String toString() { | |||
// Create a copy, don't share the array | |||
return new String(value, 0, count); | |||
} | |||
</syntaxhighlight> | |||
* “toString”方法:使用“StringFactory”根据字符数组“char[]”生成一个新的String对象并返回; | |||
== 整体框架 == | |||
框架图: | |||
:[[File:CharSequence——String框架图.jpg|400px]] | |||
:[[File:String Types In Java 8.png|600px]] | |||
应用: | |||
{| class="wikitable" style="width: 35%;" | |||
! !! 可变 !! 线程安全 | |||
|- | |||
| '''String''' | |||
| ✘ | |||
| ✔ | |||
|- | |||
| '''StringBuilder''' | |||
| ✔ | |||
| ✘ | |||
|- | |||
| '''StringBuffer''' | |||
| ✔ | |||
| ✔ | |||
|} | |||
* 根据“是否需要内容可变”、“是否在多线程环境使用”,来选择合适的类。 | |||
* 关于“'''String是线程安全的'''”: | |||
*: 因为字符数组被“final”修饰(“private final char value[];”),即字符串是不可变的,所以是多线程安全的,同一个字符串实例可以被多个线程共享。 | |||
*:(“final”:值不可修改,类不可被继承) | |||
*: PS:String类也是“final”的; |
2020年12月31日 (四) 19:54的最新版本
关于
在Java中,字符存储相关的类有 String, StringBuffer, StringBuilder, CharBuffer, CharSequence以及可以存储原始数据的 ByteBuffer。
- “CharSequence”:(接口),表示 char 值的一个可读序列,是所有String相关的接口;
- (此接口对许多不同种类的 char 序列提供统一的只读访问)
- (“CharBuffer”、“Segment”、“String”、“StringBuffer”、“StringBuilder”,都实现了“CharSequence”接口)
- “String”:不可变字符串类,最方便,效率低;
- “StringBuffer”:线程安全的字符串缓冲,比String功能差,但是快;
- “StringBuilder”:线程不安全的字符串缓冲,与StringBuffer功能相同,但是比StringBuffer更快;
PS:
- “ByteBuffer”:(抽象类,“java.nio”包中)字节缓冲,没有字符集;
- “CharBuffer”:(抽象类,“java.nio”包中)字符缓冲,没有字符串操作功能;
基础接口/抽象类
CharSequence
接口,表示char值的一个可读序列。此接口对不同种类的char序列提供统一的只读访问接口。
- 此接口不修改equals和hashCode方法;
- 实现类:“CharBuffer”、“String”、“StringBuilder”、“StringBuffer”;
package java.lang;
import . . .;
public interface CharSequence {
// 返回指定索引的 char 值
int length();
// 返回此字符序列的长度
char charAt(int index);
// 返回一个新的 CharSequence,它是此序列的子序列
CharSequence subSequence(int start, int end);
// 返回一个包含此序列中字符的字符串,该字符串与此序列的顺序相同
public String toString();
public default IntStream chars() {
. . .
}
public default IntStream codePoints() {
. . .
}
}
Appendable
接口,表示可添加char序列和值。
- 实现类:“CharBuffer”、“StringBuffer”、“StringBuilder”、“BufferedWriter”、“CharArrayWriter”、“FileWriter”等;
package java.lang;
import java.io.IOException;
public interface Appendable {
Appendable append(CharSequence csq) throws IOException;
Appendable append(CharSequence csq, int start, int end) throws IOException;
Appendable append(char c) throws IOException;
}
AbstractStringBuilder
抽象类,表示可变的字符序列。
- 实现了“CharSequence”和“Appenable”接口;
package java.lang;
import sun.misc.FloatingDecimal;
import java.util.Arrays;
abstract class AbstractStringBuilder implements Appendable, CharSequence {
char[] value;
int count;
. . .
@Override
public abstract String toString();
final char[] getValue() {
return value;
}
实用类
String
- 接口实现:
- 实现了“CharSequence”接口,为可访问的char序列;
- 实现了“Serializable”接口,可以被序列化。
- 实现了“Comparable<String>”,支持String之间的相互比较。
- 数据结构:字符数组“char[]”,存储字符的unicode值。
- 不可变:一旦生成,char[]中数据就不可变。即String内容不变。
- 重复利用:当新创建“String test = "abc"”时,JVM会到String常量池查询是否已经存在内容为“abc”的String对象:
- 如果已经存在该String,则把test设置为这个对象的引用;
- 如果不存在,则新创建一个内容为“abc”的String对象,并加入常量池。
package java.lang;
import . . .;
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
private final char value[];
private int hash; // Default to 0
private static final long serialVersionUID = -6849794470754667710L;
private static final ObjectStreamField[] serialPersistentFields =
new ObjectStreamField[0];
. . .
public native String intern();
}
- (关于“intern”方法,见“关于String.intern()”)
StringBuffer
- 继承自“AbstractStringBuilder”,实现了“Serializable”、“CharSequence”接口;
- 数据结构:使用父类“AbstractStringBuilder”中的字符数组;
- 线程安全:所有的“public”方法都添加了“synchronized”同步锁;
- 仅在“toString()”时生成String对象,且在不修改内容的情况下只生成一次;
package java.lang;
import java.util.Arrays;
public final class StringBuffer
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
{
private transient char[] toStringCache;
static final long serialVersionUID = 3388685877147921107L;
public StringBuffer() {
super(16);
}
public StringBuffer(int capacity) {
super(capacity);
}
public StringBuffer(String str) {
super(str.length() + 16);
append(str);
}
public StringBuffer(CharSequence seq) {
this(seq.length() + 16);
append(seq);
}
. . .
@Override
public synchronized String toString() {
if (toStringCache == null) {
toStringCache = Arrays.copyOfRange(value, 0, count);
}
return new String(toStringCache, true);
}
StringBuilder
- 继承自“AbstractStringBuilder”,实现了“Serializable”、“CharSequence”接口;
- 数据结构:使用父类“AbstractStringBuilder”中的字符数组;
- 可变;
- 非线程安全;
- 仅在“toString()”时生成String对象;
package java.lang;
public final class StringBuilder
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
{
static final long serialVersionUID = 4383685877147921099L;
public StringBuilder() {
super(16);
}
public StringBuilder(int capacity) {
super(capacity);
}
public StringBuilder(String str) {
super(str.length() + 16);
append(str);
}
public StringBuilder(CharSequence seq) {
this(seq.length() + 16);
append(seq);
}
. . .
@Override
public String toString() {
// Create a copy, don't share the array
return new String(value, 0, count);
}
- “toString”方法:使用“StringFactory”根据字符数组“char[]”生成一个新的String对象并返回;
整体框架
框架图:
应用:
可变 | 线程安全 | |
---|---|---|
String | ✘ | ✔ |
StringBuilder | ✔ | ✘ |
StringBuffer | ✔ | ✔ |
- 根据“是否需要内容可变”、“是否在多线程环境使用”,来选择合适的类。
- 关于“String是线程安全的”:
- 因为字符数组被“final”修饰(“private final char value[];”),即字符串是不可变的,所以是多线程安全的,同一个字符串实例可以被多个线程共享。
- (“final”:值不可修改,类不可被继承)
- PS:String类也是“final”的;