JDK源码总结之String、StringBuilder、StringBuffer

一、String定义

String是一个用 final 声明的常量类,不能被任何类所继承,而且一旦一个String对象被创建,包含在这个对象中的字符序列是不可改变的, 包括该类后续的所有方法都是不能修改该对象的。 实现了Serializable接口,这是一个序列化标志接口,还实现了Comparable接口,用于比较两个字符串的大小(按顺序比较单个字符的ASCII码),后面会有具体方法实现;最后实现了CharSequence接口,表示是一个有序字符的集合。

常量池:Java运行时会维护一个String Pool(String池), 也叫“字符串缓冲区”。String池用来存放运行时中产生的各种字符串,并且池中的字符串的内容不重复。

二、String源代码

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** 用于字符存储. */
    private final char value[];

    /** 存放hash code */
    private int hash; // Default to 0

    //在 java的很多类中都会重写equals和hashCode方法,这是为什么呢?最常见的String类,比如我定义两个字符相同的字符串,那么对它们进 行比较时,我想要的结果应该是相等的,如果你不重写equals和hashCode方法,他们肯定是不会相等的,因为两个对象的内存地址不一样。
    //先比较对象,如果不相等返回false,否则判断比较对象是否是String类型,如果不是返回false,否则比较它们的字符串长度,如果不一致则返回false,否则将它们的值一一比较,如果不一致返回false,否则返回true。
    public boolean equals(Object anObject) {
            if (this == anObject) {
                return true;
            }
            if (anObject instanceof String) {
                String anotherString = (String)anObject;
                int n = value.length;
                if (n == anotherString.value.length) {
                    char v1[] = value;
                    char v2[] = anotherString.value;
                    int i = 0;
                    while (n-- != 0) {
                        if (v1[i] != v2[i])
                            return false;
                        i++;
                    }
                    return true;
                }
            }
            return false;
    }
    
    //该算法实现数学表达式:s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
    public int hashCode() {
        int h = hash;
        if (h == 0 && value.length > 0) {
            char val[] = value;

            for (int i = 0; i < value.length; i++) {
                h = 31 * h + val[i];
            }
            hash = h;
        }
        return h;
    }
}

三、常量与变量的显著区别

String类是依赖一个私有字符常量数组实现的

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];

StringBuffer与StringBuilder都是继承AbstractStringBuilder,然而AbstractStringBuilder类是依赖一个字符变量数组实现的

abstract class AbstractStringBuilder implements Appendable, CharSequence {
    /**
     * The value is used for character storage.
     */
    char[] value;

四、线程安全分析

所有对String发生修改的方法返回值都是一个新的String对象,没有修改原有对象

public String replace(char oldChar, char newChar) {
        if (oldChar != newChar) {
            int len = value.length;
            int i = -1;
            char[] val = value; /* avoid getfield opcode */
            while (++i < len) {
                if (val[i] == oldChar) {
                    break;
                }
            }
            if (i < len) {
                char buf[] = new char[len];
                for (int j = 0; j < i; j++) {
                    buf[j] = val[j];
                }
                while (i < len) {
                    char c = val[i];
                    buf[i] = (c == oldChar) ? newChar : c;
                    i++;
                }
                return new String(buf, true);
            }
        }
        return this;
    }

StringBuffer所有写操作都被synchronized修饰了,所以所有修改操作都是串行的

@Override
    public synchronized StringBuffer replace(int start, int end, String str) {
        toStringCache = null;
        super.replace(start, end, str);
        return this;
    }

而StringBuilder的写操作则没有使用synchronized进行修饰,也不包含其他串行化修改的算法,多线程情况下会出错

@Override
    public StringBuilder replace(int start, int end, String str) {
        super.replace(start, end, str);
        return this;
    }

五、性能、速度分析

StringBuilder > StringBuffer > String

(1) 在编译阶段就能够确定的字符串常量,完全没有必要创建String或StringBuffer对象。直接使用字符串常量的"+"连接操作效率最高。如:

 str = "a" + "b";

(2) 此外StringBuffer对象的append效率要高于String对象的"+"连接操作。如:

 String s1="Heart";
    String s="";
    for(int i=0;i<10000;i++){  
       s=s+s1;
    }  

(3)StringBuffer使用了synchronized,效率相对低一些。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值