Java源代码阅读——字符串相关

    xiaoxiao2021-03-25  193

    一 String类

     

    字符串存贮在一个final数组value中,并且未对外提供修改其内元素的方法,所以String类是不可变的。

     

     

     

    private final char value[];

     

     

     

    1.1 构造方法

     

     

     

    public String() { this.value = "".value; } public String(String original) { this.value = original.value; this.hash = original.hash; } public String(char value[]) { this.value = Arrays.copyOf(value, value.length); } 通过上述构造方法可知, 字符串的构造是通过将一个数组赋给当前String的value数组完成的。   public String(StringBuffer buffer) { synchronized(buffer) { this.value = Arrays.copyOf(buffer.getValue(), buffer.length()); } } public String(StringBuilder builder) { this.value = Arrays.copyOf(builder.getValue(), builder.length()); } 由上述可知,用StringBuffer构造字符串是线程安全的,而StringBuilder是线程不安全的, 通常应该优先使用StringBuilder 类,因为它支持所有与StringBuffer相同的操作,但由于它不执行同步,所以速度更快

     

    1.2 length()和empty()

     

     

    public int length() { return value.length; }

     

     

    public boolean isEmpty() { return value.length == 0; }

     

    length通过返回数组的长度取得。

    1.3 charAt()

     

    public char charAt(int index) { if ((index < 0) || (index >= value.length)) { throw new StringIndexOutOfBoundsException(index); } return value[index]; } 返回该索引对饮的数组值。

     

    1.5 indexOf()

     

    public int indexOf(int ch, int fromIndex) { final int max = value.length; if (fromIndex < 0) { fromIndex = 0; } else if (fromIndex >= max) { // Note: fromIndex might be near -1>>>1. return -1; } if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) { // handle most cases here (ch is a BMP code point or a // negative value (invalid code point)) final char[] value = this.value; for (int i = fromIndex; i < max; i++) { if (value[i] == ch) { return i; } } return -1; } else { return indexOfSupplementary(ch, fromIndex); } } 通过返回ch在value中的所有取得。

     

    1.6 subString()

     

    public String substring(int beginIndex) { if (beginIndex < 0) { throw new StringIndexOutOfBoundsException(beginIndex); } int subLen = value.length - beginIndex; if (subLen < 0) { throw new StringIndexOutOfBoundsException(subLen); } return (beginIndex == 0) ? this : new String(value, beginIndex, subLen); } 若beginIndex==0则直接返回当前String,否则new一个新String。

     

    1.7 replace()

     

    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; } 如果确实发生了字符替换,将会new 一个新的String返回。toUpperCase()等若发生改变也返回的是新的String。

     

    1.8 intern

     

    public native String intern();

     

    如果池已经包含一个等于此 String 对象的字符串(该对象由 equals(Object) 方法确定),则返回池中的字符串。否则,将此 String 对象添加到池中,并且返回此 String 对象的引用。 

    二 StringBuffer类

    2.1 构造函数

     

    public StringBuffer() { super(16); } 其父类构造函数为:

     

     

    AbstractStringBuilder(int capacity) { value = new char[capacity]; } 即默认构造了 大小为16的数组。   public StringBuffer(String str) { super(str.length() + 16); append(str); } 构造一个比当前字符串长16的字符串。

     

    2.2 append()

     

    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; }   private void ensureCapacityInternal(int minimumCapacity) { // overflow-conscious code if (minimumCapacity - value.length > 0) expandCapacity(minimumCapacity); } void expandCapacity(int minimumCapacity) { int newCapacity = value.length * 2 + 2; if (newCapacity - minimumCapacity < 0) newCapacity = minimumCapacity; if (newCapacity < 0) { if (minimumCapacity < 0) // overflow throw new OutOfMemoryError(); newCapacity = Integer.MAX_VALUE; } value = Arrays.copyOf(value, newCapacity); } 每次扩容为原数组长度的2倍+2,若不够则取count+len,即每次扩容胡至少为minimumCapacity=count+len。

     

    三 StringBuilder类

    3.1 构造函数

     

    public StringBuilder() { super(16); }

     

    类似StringBuffer。

    四 StringBuffer VS StringBuilder

    StringBuffer类的成员方法前面多了一个关键字:synchronized,所以它是线程安全的,由此带来的问题是效率低。

    转载请注明原文地址: https://ju.6miu.com/read-607.html

    最新回复(0)