String类:
StringBuilder类:
StringBuffer类:
/*
final修饰,不能被继承,不可修改
java.io.Serializable:序列化接口仅用于标识序列化。
序列化:对象转换成字节流的一个过程,用来处理对象流的机制。
Comparable:接口用于对两个实例化对象比较大小。
CharSequence:只读的字符序列;
抽象方法length(), charAt(int index), subSequence(int start, int end)
public String toString();
*/
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
hash = h = isLatin1() ? StringLatin1.hashCode(value)
: StringUTF16.hashCode(value);
}
return h;
}
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String aString = (String)anObject;
if (coder() == aString.coder()) {
return isLatin1() ? StringLatin1.equals(value, aString.value)
: StringUTF16.equals(value, aString.value);
}
}
return false;
}
}
final class StringLatin1 {
public static boolean equals(byte[] value, byte[] other) {
if (value.length == other.length) {
for (int i = 0; i < value.length; i++) {
if (value[i] != other[i]) {
return false;
}
}
return true;
}
return false;
}
public static int hashCode(byte[] value) {
int h = 0;
int length = value.length >> 1;
for (int i = 0; i < length; i++) {
h = 31 * h + getChar(value, i);
}
return h;
}
}
final class StringUTF16 {
public static int hashCode(byte[] value) {
int h = 0;
int length = value.length >> 1;
for (int i = 0; i < length; i++) {
h = 31 * h + getChar(value, i);
}
return h;
}
@HotSpotIntrinsicCandidate
public static boolean equals(byte[] value, byte[] other) {
if (value.length == other.length) {
int len = value.length >> 1;
for (int i = 0; i < len; i++) {
if (getChar(value, i) != getChar(other, i)) {
return false;
}
}
return true;
}
return false;
}
}
特点:
public final class StringBuilder extends AbstractStringBuilder
implements java.io.Serializable, CharSequence{
static final long serialVersionUID = 4383685877147921099L;
@HotSpotIntrinsicCandidate
public StringBuilder() {
super(16);
}
@HotSpotIntrinsicCandidate
public StringBuilder(int capacity) {
super(capacity);
}
@HotSpotIntrinsicCandidate
public StringBuilder(String str) {
super(str.length() + 16);
append(str);
}
public StringBuilder(CharSequence seq) {
this(seq.length() + 16);
append(seq);
}
//个append 方法
public StringBuilder append(String str) {
super.append(str);
return this;
}
public StringBuilder append(StringBuffer sb) {
super.append(sb);
return this;
}
}
//抽线类,这个抽象类值得好好看看
abstract class AbstractStringBuilder implements Appendable, CharSequence {
byte[] value;//The value is used for character storage.
byte coder;//The id of the encoding used to encode the bytes in {@code value}.
int count;//The count is the number of characters used.
public AbstractStringBuilder append(String str) {
if (str == null) {
return appendNull();
}
int len = str.length();
ensureCapacityInternal(count + len);
putStringAt(count, str);
count += len;
return this;
}
private AbstractStringBuilder appendNull() {
ensureCapacityInternal(count + 4);
int count = this.count;
byte[] val = this.value;
if (isLatin1()) {
val[count++] = 'n';
val[count++] = 'u';
val[count++] = 'l';
val[count++] = 'l';
} else {
count = StringUTF16.putCharsAt(val, count, 'n', 'u', 'l', 'l');
}
this.count = count;
return this;
}
private void ensureCapacityInternal(int minimumCapacity) {
//移位运算符;<<(左移)、>>(带符号右移)、>>>(无符号右移)
int oldCapacity = value.length >> coder;
if (minimumCapacity - oldCapacity > 0) {
value = Arrays.copyOf(value,newCapacity(minimumCapacity) << coder);
}
}
private int newCapacity(int minCapacity) {
int oldCapacity = value.length >> coder;
int newCapacity = (oldCapacity << 1) + 2;
if (newCapacity - minCapacity < 0) {
newCapacity = minCapacity;
}
int SAFE_BOUND = MAX_ARRAY_SIZE >> coder;
return (newCapacity <= 0 || SAFE_BOUND - newCapacity < 0)
? hugeCapacity(minCapacity): newCapacity;
}
private final void putStringAt(int index, String str) {
if (getCoder() != str.coder()) {
inflate();
}
str.getBytes(value, index, coder);
}
}
特点:
transient:不希望在网络操作(主要涉及到序列化操作,本地序列化缓存也适用)中被传输,这些信息对应的变量就可以加上transient关键字。换句话说,这个字段的生命周期仅存于调用者的内存中而不会写到磁盘里持久化。
public final class StringBuffer
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
{
private transient String toStringCache;
@Override
public synchronized int length() {
return count;
}
@Override
public synchronized int capacity() {
return super.capacity();
}
@Override
public synchronized void ensureCapacity(int minimumCapacity) {
super.ensureCapacity(minimumCapacity);
}
@Override
public synchronized StringBuffer append(Object obj) {
toStringCache = null;
super.append(String.valueOf(obj));
return this;
}
@Override
@HotSpotIntrinsicCandidate
public synchronized StringBuffer append(String str) {
toStringCache = null;
super.append(str);
return this;
}
@Override
@HotSpotIntrinsicCandidate
public synchronized StringBuffer append(String str) {
toStringCache = null;
super.append(str);
return this;
}
}
import org.junit.Test;
import java.util.concurrent.CountDownLatch;
public class StringDiff {
@Test
public void testStr() {
String str = "Hello";
long start = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
str+="1";
//str=str.concat("1");
}
long end = System.currentTimeMillis();
System.out.println(end - start);
}
/* 被synchronized修饰*/
@Test
//线程安全
public void testStrBuilder() {
StringBuilder str = new StringBuilder("Hello");
long start = System.currentTimeMillis();
for (int i = 0; i < 10000000; i++) {
str.append("BoGe");
}
long end = System.currentTimeMillis();
System.out.println("StringBuilder测试:"+(end - start));
}
@Test
//线程不安全
public void testStrBuffer() {
StringBuffer str = new StringBuffer("Hello");
long start = System.currentTimeMillis();
for (int i = 0; i < 10000000; i++) {
str.append("BoGe");
}
long end =System.currentTimeMillis();
System.out.println("StringBuffer测试:"+(end-start));
}
/**CountDownLatch原理:
* CountDownLatch是通过一个计数器来实现的,计数器的初始化值为线程的数量。每当一个线程完成了自己的任务后,计数器的值就相应得减1。
* 当计数器到达0时,表示所有的线程都已完成任务,然后在闭锁上等待的线程就可以恢复执行任务。
*/
@SuppressWarnings("all")
@Test
public void testStringBuilderAndStringBuffer() {
CountDownLatch latch1 = new CountDownLatch(1000);
CountDownLatch latch2 = new CountDownLatch(1000);
StringBuffer stringBuffer = new StringBuffer();
StringBuilder stringBuilder = new StringBuilder();
for(int i=0;i<1000;i++){
new Thread(new Runnable() {
@Override
public void run() {
try {
stringBuilder.append(1);
} catch (Exception e) {
e.printStackTrace();
} finally {
latch1.countDown();
}
}
}).start();
}
for(int i=0;i<1000;i++){
new Thread(new Runnable() {
@Override
public void run() {
try {
stringBuffer.append(1);
} catch (Exception e) {
e.printStackTrace();
} finally {
// 递减计数器的计数,如果计数到达零,则释放所有等待的线程。
latch2.countDown();
}
}
}).start();
}
try {
latch1.await();
System.out.println(stringBuilder.length());
latch2.await();
System.out.println(stringBuffer.length());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}