文章目录
  1. 1. 1.String之我见
  2. 2. 2.StringBuilder

1.String之我见

  • Java字符串就是Unicode字符序列
  • String在java中不是基本类型,是一个类,其实现是通过final char value[],所以查询、替换和数组一样;
  • public final class String 说明String 是不可变的,类中每个看起来会修改值的方法都是创建了一个新的对象
    就像有个字符串池,字符常量存放在常量池中,字符串变量指向字符串池中的相对应的位置。
    实际上,池中的字符串常量是可以共享的。
    字符串变量相当于对象变量,是不可以共享的
    这样设计是因为字符串很少修改,但是很多时候需要共享,防止出现很多人使用同一字符串时,
    有一人修改字符串,而导致的错误
  • “==”和equals
    “==”比较的是s1和s2的内存地址,是一样则返回true
    equals比较的是他们的字面量,如果两个字符串是一样的则返回true

    1
    2
    3
    4
    5
    6
    7
    8
    9
    String s1 = new String("ok");//new(),返回的是字符串“ok”在内存中的地址,这里的s1是对象变量保存的是内存地址,
    //是不可以共享的

    String s12 = new String("ok");
    //s1 = s12,则s1 == s12,

    System.out.println(s1 == s12);//false

    String s2 = "ok";//s2是字符串常量可以共享
    String s22 = "ok";
    System.out.println(s2 == s22);//true
  • hashCode()
    一般情况下,是保存对象的内存地址,但是String中重写了hashCode方法,根据的是字符串的内容生成的,所以如果两个
    字符串的内容相同,其hashCode一定相同

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    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;
    }
  • replace:char[] val = value,新的字符数组进行操作,先找到,在替换,之后返回替换后的数组buf[i]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    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;
    }

2.StringBuilder

  • StringBuilder是从StringBuffer那里演进过来的,StringBuffer是线程安全的,但是StringBuilder并不是线程安全
  • StringBuilder,其内部采用动态数组的形式实现,操作的是数组本身拼接完成再将其转换成字符串
  • 实现:
    public AbstractStringBuilder append(String str) {

    if (str == null) str = "null";
    int len = str.length();
    ensureCapacityInternal(count + len);
    str.getChars(0, len, value, count);
    count += len;
    return this;
    

    }

  • delete:把要被删除元素的后边的元素往前挪了END - START个位置。然后按长度取,insert类似,现将后移,在插入

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public AbstractStringBuilder delete(int start, int end) {
    if (start < 0)
    throw new StringIndexOutOfBoundsException(start);
    if (end > count)
    end = count;
    if (start > end)
    throw new StringIndexOutOfBoundsException();
    int len = end - start;
    if (len > 0) {
    System.arraycopy(value, start+len, value, start, count-end);
    count -= len;
    }
    return this;
    }
文章目录
  1. 1. 1.String之我见
  2. 2. 2.StringBuilder