📄 mutablestring.java
字号:
* @param dest destination array. * @param destStart the first character will be copied in <code>dest[destStart]</code>. * @see java.lang.String#getChars(int,int,char[],int) */ protected static void getChars( final CharSequence s, final int start, final int end, final char[] dest, final int destStart ) { int j = destStart, i = start; while( i < end ) dest[ j++ ] = s.charAt( i++ ); } /** Returns the number of characters in this mutable string. * * @return the length of this mutable string. */ final public int length() { return hashLength >= 0 ? hashLength : array.length; } /** Returns the current length of the backing array. * * @return the current length of the backing array. */ final public int capacity() { return array.length; } /** Gets the backing array. * * <P>For fast, repeated access to the characters of this mutable string, * you can obtain the actual backing array. Be careful, and if this mutable * string is compact do <em>not</em> modify its backing array without * calling {@link #changed()} immediately afterwards (or the cached hash * code will get out of sync, with unforeseeable consequences). * * @see #changed() * @return the backing array. */ final public char[] array() { return array; } /** Characters with indices from <code>start</code> (inclusive) to * index <code>end</code> (exclusive) are copied from this * mutable string into the array <code>dest</code>, starting * from index <code>destStart</code>. * * @param start copy start from this index (inclusive). * @param end copy ends at this index (exclusive). * @param dest destination array. * @param destStart the first character will be copied in <code>dest[destStart]</code>. * * @see String#getChars(int,int,char[],int) * @throws NullPointerException if <code>dest</code> is <code>null</code>. * @throws IndexOutOfBoundsException if any of the following is true: * <ul> * <li><code>start</code> or <code>end</code> is negative * <li><code>start</code> is greater than * <code>end</code> * <li><code>end</code> is greater than * {@link #length()} * <li><code>end-start+destStart</code> is greater than * <code>dest.length</code> * </ul> */ final public void getChars( final int start, final int end, final char[] dest, final int destStart ) { if ( end > length() ) throw new IndexOutOfBoundsException(); System.arraycopy( array, start, dest, destStart, end - start ); } /** Ensures that at least the given number of characters can be stored in this mutable string. * * <P>The new capacity of this string will be <em>exactly</em> equal to the * provided argument if this mutable string is compact (this differs * markedly from {@link java.lang.StringBuffer#ensureCapacity(int) * StringBuffer}). If this mutable string is loose, the provided argument * is maximised with the current capacity doubled. * * <P>Note that if the given argument is greater than the current length, you will make * this string loose (see the {@linkplain MutableString class description}). * * @param minimumCapacity we want at least this number of characters, but no more. * @return this mutable string. */ final public MutableString ensureCapacity( final int minimumCapacity ) { final int length = length(); expand( minimumCapacity ); if ( length < minimumCapacity ) hashLength = length; return this; } /** Ensures that at least the given number of characters can be stored in this string. * * <P>If necessary, enlarges the backing array. If the string is compact, * we expand it exactly to the given capacity; otherwise, expand to the * maximum between the given capacity and the double of the current capacity. * * <P>This method works even with a <code>null</code> backing array (which * will be considered of length 0). * * <P>After a call to this method, we may be in an inconsistent state: if * you expand a compact string, {@link #hashLength} will be negative, * but there will be spurious characters in the string. Be sure to * fill them suitably. * * @param minimumCapacity we want at least this number of characters. */ private void expand( final int minimumCapacity ) { final int c = array == null ? 0 : array.length; // This can happen only deserialising. if ( minimumCapacity <= c && array != null ) return; final int length = hashLength >= 0 ? hashLength : c; final char[] newArray = new char[ hashLength >= 0 && c * 2 > minimumCapacity ? c * 2 // loose : minimumCapacity // compact ]; if ( length != 0 ) System.arraycopy( array, 0, newArray, 0, length ); // We check because array could be null during deserialisation. array = newArray; } /** Ensures that <em>exactly</em> the given number of characters can be stored in this string. * * <P>If necessary, reallocates the backing array. If the new capacity is smaller than * the string length, the string will be truncated. * * <P>After a call to this method, we may be in an inconsistent state: if * you expand a compact string, {@link #hashLength} will be negative, * but there will be additional NUL characters in the string. Be sure to * substitute them suitably. * * @param capacity we want exactly this number of characters. */ private void setCapacity( int capacity ) { final int c = array.length; if ( capacity == c ) return; final int length = hashLength >= 0 ? hashLength : c; final char[] newArray = capacity != 0 ? new char[ capacity ] : CharArrays.EMPTY_ARRAY; System.arraycopy( array, 0, newArray, 0, length < capacity ? length : capacity ); array = newArray; } /** Sets the length. * * <P>If the provided length is greater than that of the current string, * the string is padded with zeros. If it is shorter, the string is * truncated to the given length. We do <em>not</em> reallocate the backing * array, to increase object reuse. Use rather {@link #compact()} for that * purpose. * * <P>Note that shortening a string will make it loose (see the {@linkplain * MutableString class description}). * * @param newLength the new length for this mutable string. * @return this mutable string. * @see #compact() */ final public MutableString length( final int newLength ) { if ( newLength < 0 ) throw new IllegalArgumentException( "Negative length (" + newLength + ")" ); if ( hashLength < 0 ) { if ( array.length == newLength ) return this; hashLength = -1; setCapacity( newLength ); // For compact strings, length and capacity coincide. } else { final int length = hashLength; if ( newLength == length ) return this; if ( newLength > array.length ) expand( newLength ); // In this case, the array is already filled with zeroes. else if ( newLength > length ) java.util.Arrays.fill( array, length, newLength, '\0' ); hashLength = newLength; } return this; } /** A nickname for {@link #length(int)}. * * @param newLength the new length for this mutable string. * @return this mutable string. * @see #length(int) */ final public MutableString setLength( final int newLength ) { return length( newLength ); } /** Makes this mutable string compact (see the {@linkplain MutableString class description}). * * <P>Note that this operation may require reallocating * the backing array (of course, with a shorter length). * * @return this mutable string. * @see #isCompact() */ final public MutableString compact() { if ( hashLength >= 0 ) { setCapacity( hashLength ); hashLength = -1; } return this; } /** Makes this mutable string loose. * * @return this mutable string. * @see #isLoose() */ final public MutableString loose() { if ( hashLength < 0 ) hashLength = array.length; return this; } /** Returns whether this mutable string is compact (see the {@linkplain MutableString class description}). * * @return whether this mutable string is compact. * @see #compact() */ final public boolean isCompact() { return hashLength < 0; } /** Returns whether this mutable string is loose (see the {@linkplain MutableString class description}). * * @return whether this mutable string is loose. * @see #loose() */ final public boolean isLoose() { return hashLength >= 0; } /** Invalidates the current cached hash code if this mutable string is compact. * * <P>You will need to call this method only if you change the backing * array of a compact mutable string {@linkplain #array() directly}. * * @return this mutable string. */ final public MutableString changed() { if ( hashLength < 0 ) hashLength = -1; return this; } /** Wraps a given character array in a compact mutable string. * * <P>The returned mutable string will be compact and backed by the given character array. * * @param a a character array. * @return a compact mutable string backed by the given array. */ static public MutableString wrap( final char a[] ) { MutableString s = new MutableString( 0 ); s.array = a; s.hashLength = -1; return s; } /** Wraps a given character array for a given length in a loose mutable string. * * <P>The returned mutable string will be loose and backed by the given character array. * * @param a a character array. * @param length a length. * @return a loose mutable string backed by the given array with the given length. */ static public MutableString wrap( final char[] a, final int length ) { MutableString s = new MutableString( 0 ); s.array = a; s.hashLength = length; return s; } /** Gets a character. * * <P>If you end up calling repeatedly this method, you * should consider using {@link #array()} instead. * * @param index the index of a character. * @return the chracter at that index. */ final public char charAt( final int index ) { if ( index >= length() ) throw new StringIndexOutOfBoundsException( index ); return array[ index ]; } /** A nickname for {@link #charAt(int,char)}. * * @param index the index of a character. * @param c the new character. * @return this mutable string. * @see #charAt(int,char) */ final public MutableString setCharAt( final int index, final char c ) { charAt( index, c ); return this; } /** Sets the character at the given index. * * <P>If you end up calling repeatedly this method, you should consider * using {@link #array()} instead. * * @param index the index of a character. * @param c the new character. * @return this mutable string. */ final public MutableString charAt( final int index, final char c ) { if ( index >= length() ) throw new StringIndexOutOfBoundsException( index ); array[ index ] = c; changed(); return this; } /** Returns the first character of this mutable string. * * @return the first character. * @throws StringIndexOutOfBoundsException when called on the empty string. */ final public char firstChar() { if ( length() == 0 ) throw new StringIndexOutOfBoundsException( 0 ); return array[ 0 ]; } /** Returns the last character of this mutable string. * * @return the last character. * @throws ArrayIndexOutOfBoundsException when called on the empty string. */ final public char lastChar() { return array[ length() - 1 ]; } /** Converts this string to a new character array. * * @return a newly allocated character array with the same length and content of this mutable string. */ final public char[] toCharArray() { return CharArrays.copy( array, 0, length() ); } /** Returns a substring of this mutable string. * * <P>The creation of a substring implies the creation of a new backing * array. The returned mutable string will be compact. * * @param start first character of the substring (inclusive). * @param end last character of the substring (exclusive). * @return a substring defined as above. */ final public MutableString substring( final int start, final int end ) { if ( end > length() ) throw new StringIndexOutOfBoundsException( end ); return new MutableString( array, start, end - start ); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -