美文网首页
第十三章 字符串

第十三章 字符串

作者: 浩林Leon | 来源:发表于2017-12-20 23:21 被阅读9次

    13.1 String, StringBuilder ,StringBuffer

    字符串的+, 在普通的的一条语句,编译器会自动创建StringBuilder ,然后执行append.此时的效率和StringBuilder 基本一致.但是在循环语句中,使用多条语句对字符串进行累加.则每次操作都会创建一个StringBuffer对象,这样会增加创建对象的开销.

    StringBuilder 是一种可变字符,但是不支持线程同步操作.
    StringBuffer 是线程同步的在所有的写方法加了synchronized锁.其他的之外StringBuilder 的基本一致,最终的一些操作都是调用基类AbstractStringBuilder的操作,

    对StringBuilder, StringBuffer的append方法解读:

    1.StringBuilder ,StringBuffer 的append 方法列表:

    image.png
    2.append 可以添加null对象,并且会把他当做”null”字符串,所以这里需要注意.
    在append(boolean )--->最终会添加 ”ture” 或者”false”.
    image.png
    append(char char) :直接在value 后面添加一个char
    @Override
    public AbstractStringBuilder append(char c) {
        ensureCapacityInternal(count + 1);
        value[count++] = c;
        return this;
    }
    

    appeand(char[] str)

    public AbstractStringBuilder append(char[] str) {
        int len = str.length;
        ensureCapacityInternal(count + len);
        System.arraycopy(str, 0, value, count, len);
        count += len;
        return this;
    }
    

    append(String str)

    public AbstractStringBuilder append(String str) {
        if (str == null)
            return appendNull();
        int len = str.length();
        ensureCapacityInternal(count + len);
        str.getChars(0, len, value, count);
        count += len;
        return this;
    }
    

    [Android sdk] str.getChars 是String 类的一个copy到字符字符数组中, 最终调用的getCharNoCheck是一个本地方法

     public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {   
       ...
        getCharsNoCheck(srcBegin, srcEnd, dst, dstBegin);
    }
    

    [标准java openjdk1.8]

    public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
        System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
    }
    

    查看java openjdk 源码openjdk/jdk/src/share/native/java/lang/System.c: 可以找到对应的native代码:

    /* Only register the performance-critical methods */
    static JNINativeMethod methods[] = {
        {"currentTimeMillis", "()J",              (void *)&JVM_CurrentTimeMillis},
        {"nanoTime",          "()J",              (void *)&JVM_NanoTime},
        {"arraycopy",     "(" OBJ "I" OBJ "II)V", (void *)&JVM_ArrayCopy},
    };
    

    查询到 JVM_ArrayCopy函数,在openjdk/hotspot/src/share/vm/prims/jvm.cpp

    JVM_ENTRY(void, JVM_ArrayCopy(JNIEnv *env, jclass ignored, jobject src, jint src_pos,
                                   jobject dst, jint dst_pos, jint length))
    ...
      s->klass()->copy_array(s, src_pos, d, dst_pos, length, thread);
    JVM_END
    

    最终到达java 虚拟机的底层操作系统,进行memcpy()内存级别的字符拷贝.

    13.3 无意识的递归

    在对象的toString() 中不要进行类似写法:

    public void toString(){
    System.out.println(“xxx”+this+"dddd") ;
    }
    

    因为在进行操作符重载的过程中,发现 前面的是字符串,而this 是对象,会进行自动的调用 toString,而这时候.toString形成了无线递归操作.正确的做法是调用 super.toString();

    正则表达式:Pattern ,Scanner, StringTokenizer

    相关文章

      网友评论

          本文标题:第十三章 字符串

          本文链接:https://www.haomeiwen.com/subject/biznwxtx.html