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

第十三章 字符串

作者: 浩林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