* The {@code String} classrepresentscharacterstrings. All * stringliteralsinJavaprograms, suchas{@code"abc"}, are * implemented as instances of this class. * <p> * Strings are constant; their values cannot be changed after they * are created. String buffers support mutable strings. * Because String objects are immutable they can be shared.
/** Cache the hash code for the string */ privateint hash; // Default to 0
/** use serialVersionUID from JDK 1.0.2 for interoperability */ privatestaticfinallong serialVersionUID = -6849794470754667710L;
/** * Class String is special cased within the Serialization Stream Protocol. * * A String instance is written into an ObjectOutputStream according to * <a href="{@docRoot}/../platform/serialization/spec/output.html"> * Object Serialization Specification, Section 6.2, "Stream Elements"</a> */ privatestaticfinal ObjectStreamField[] serialPersistentFields = new ObjectStreamField[0];
/** * Compares this string to the specified object. The result is {@code * true} if and only if the argument is not {@code null} and is a {@code * String} object that represents the same sequence of characters as this * object. * * @param anObject * The object to compare this {@code String} against * * @return {@code true} if the given object represents a {@code String} * equivalent to this string, {@code false} otherwise * * @see #compareTo(String) * @see #equalsIgnoreCase(String) * 判断对象存储内容是否相同 */ publicbooleanequals(Object anObject){ if (this == anObject) {// 首先判断是否属于同一对象 returntrue; } if (anObject instanceof String) { // 类型String----长度---数组中的字符 String anotherString = (String)anObject; int n = value.length; if (n == anotherString.value.length) { char v1[] = value; char v2[] = anotherString.value; int i = 0; while (n-- != 0) {// 循环判断不等 if (v1[i] != v2[i]) returnfalse; i++; } returntrue; } } returnfalse; }
/** * Compares this {@code String} to another {@code String}, ignoring case * considerations. Two strings are considered equal ignoring case if they * are of the same length and corresponding characters in the two strings * are equal ignoring case. * * <p> Two characters {@code c1} and {@code c2} are considered the same * ignoring case if at least one of the following is true: * <ul> * <li> The two characters are the same (as compared by the * {@code ==} operator) * <li> Applying the method {@link * java.lang.Character#toUpperCase(char)} to each character * produces the same result * <li> Applying the method {@link * java.lang.Character#toLowerCase(char)} to each character * produces the same result * </ul> * * @param anotherString * The {@code String} to compare this {@code String} against * * @return {@code true} if the argument is not {@code null} and it * represents an equivalent {@code String} ignoring case; {@code * false} otherwise * * @see #equals(Object) */ publicbooleanequalsIgnoreCase(String anotherString){ return (this == anotherString) ? true : (anotherString != null) && (anotherString.value.length == value.length) && regionMatches(true, 0, anotherString, 0, value.length); }
/** * Tests if two string regions are equal. * <p> * A substring of this {@code String} object is compared to a substring * of the argument {@code other}. The result is {@code true} if these * substrings represent character sequences that are the same, ignoring * case if and only if {@code ignoreCase} is true. The substring of * this {@code String} object to be compared begins at index * {@code toffset} and has length {@code len}. The substring of * {@code other} to be compared begins at index {@code ooffset} and * has length {@code len}. The result is {@code false} if and only if * at least one of the following is true: * <ul><li>{@code toffset} is negative. * <li>{@code ooffset} is negative. * <li>{@code toffset+len} is greater than the length of this * {@code String} object. * <li>{@code ooffset+len} is greater than the length of the other * argument. * <li>{@code ignoreCase} is {@code false} and there is some nonnegative * integer <i>k</i> less than {@code len} such that: * <blockquote><pre> * this.charAt(toffset+k) != other.charAt(ooffset+k) * </pre></blockquote> * <li>{@code ignoreCase} is {@code true} and there is some nonnegative * integer <i>k</i> less than {@code len} such that: * <blockquote><pre> * Character.toLowerCase(this.charAt(toffset+k)) != Character.toLowerCase(other.charAt(ooffset+k)) * </pre></blockquote> * and: * <blockquote><pre> * Character.toUpperCase(this.charAt(toffset+k)) != * Character.toUpperCase(other.charAt(ooffset+k)) * </pre></blockquote> * </ul> * * @param ignoreCase if {@code true}, ignore case when comparing * characters. * @param toffset the starting offset of the subregion in this * string. * @param other the string argument. * @param ooffset the starting offset of the subregion in the string * argument. * @param len the number of characters to compare. * @return {@code true} if the specified subregion of this string * matches the specified subregion of the string argument; * {@code false} otherwise. Whether the matching is exact * or case insensitive depends on the {@code ignoreCase} * argument. */ publicbooleanregionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len){ char ta[] = value; int to = toffset; char pa[] = other.value; int po = ooffset; // Note: toffset, ooffset, or len might be near -1>>>1. if ((ooffset < 0) || (toffset < 0) || (toffset > (long)value.length - len) || (ooffset > (long)other.value.length - len)) { returnfalse; } while (len-- > 0) { char c1 = ta[to++]; char c2 = pa[po++]; if (c1 == c2) { continue; } if (ignoreCase) { // If characters don't match but case may be ignored, // try converting both characters to uppercase. // If the results match, then the comparison scan should // continue. char u1 = Character.toUpperCase(c1); char u2 = Character.toUpperCase(c2); if (u1 == u2) { continue; } // Unfortunately, conversion to uppercase does not work properly // for the Georgian alphabet, which has strange rules about case // conversion. So we need to make one last check before // exiting. if (Character.toLowerCase(u1) == Character.toLowerCase(u2)) { continue; } } returnfalse; } returntrue; }
/** * Tests if the substring of this string beginning at the * specified index starts with the specified prefix. * * @param prefix the prefix. * @param toffset where to begin looking in this string. * @return {@code true} if the character sequence represented by the * argument is a prefix of the substring of this object starting * at index {@code toffset}; {@code false} otherwise. * The result is {@code false} if {@code toffset} is * negative or greater than the length of this * {@code String} object; otherwise the result is the same * as the result of the expression * <pre> * this.substring(toffset).startsWith(prefix) * </pre> */ publicbooleanstartsWith(String prefix, int toffset){ char ta[] = value; int to = toffset; char pa[] = prefix.value; int po = 0; int pc = prefix.value.length; // Note: toffset might be near -1>>>1. if ((toffset < 0) || (toffset > value.length - pc)) { returnfalse; } while (--pc >= 0) { if (ta[to++] != pa[po++]) { returnfalse; } } returntrue; }
endsWith
判断字符串对象是否以指定的str结尾,源码中转换成startsWith处理。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
/** * Tests if this string ends with the specified suffix. * * @param suffix the suffix. * @return {@code true} if the character sequence represented by the * argument is a suffix of the character sequence represented by * this object; {@code false} otherwise. Note that the * result will be {@code true} if the argument is the * empty string or is equal to this {@code String} object * as determined by the {@link #equals(Object)} method. */ publicbooleanendsWith(String suffix){ return startsWith(suffix, value.length - suffix.value.length); }
获取功能
length
获取字符串的长度,其实也就是字符个数
1 2 3 4 5 6 7 8 9 10 11 12
/** * Returns the length of this string. * The length is equal to the number of <a href="Character.html#unicode">Unicode * code units</a> in the string. * 返回字符串的长度,长度等于字符串中的Unicode代码单元的数目(UTF-16的代码单元的数目) * * @return the length of the sequence of characters represented by this * object. */ publicintlength(){ return value.length; }
charAt
获取指定索引处的字符
indexOf
获取str在字符串对象中第一次出现的索引
substring(int start,int end)
从start开始,到end结束截取字符串。包括start,不包括end
转换功能
toCharArray
把字符串转换为字符数组
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/** * Converts this string to a new character array. * * @return a newly allocated character array whose length is the length * of this string and whose contents are initialized to contain * the character sequence represented by this string. */ publicchar[] toCharArray() { // Cannot use Arrays.copyOf because of class initialization order issues /** * 1. String 和Arrays 都属于rt.jar中的类,但是BootstrapClassloader在加载这两个类的顺序是不同的。 * 2. 所以当String.class被加载进内存的时候,Arrays此时没有被加载,所以直接使用肯定会抛异常。 * 3. 而System.arrayCopy是使用native代码,则不会有这个问题。 */ char result[] = newchar[value.length]; System.arraycopy(value, 0, result, 0, value.length); return result; }
/** * Returns a string whose value is this string, with any leading and trailing * whitespace removed. * <p> * If this {@code String} object represents an empty character * sequence, or the first and last characters of character sequence * represented by this {@code String} object both have codes * greater than {@code '\u005Cu0020'} (the space character), then a * reference to this {@code String} object is returned. * <p> * Otherwise, if there is no character with a code greater than * {@code '\u005Cu0020'} in the string, then a * {@code String} object representing an empty string is * returned. * <p> * Otherwise, let <i>k</i> be the index of the first character in the * string whose code is greater than {@code '\u005Cu0020'}, and let * <i>m</i> be the index of the last character in the string whose code * is greater than {@code '\u005Cu0020'}. A {@code String} * object is returned, representing the substring of this string that * begins with the character at index <i>k</i> and ends with the * character at index <i>m</i>-that is, the result of * {@code this.substring(k, m + 1)}. * <p> * This method may be used to trim whitespace (as defined above) from * the beginning and end of a string. * * @return A string whose value is this string, with any leading and trailing white * space removed, or this string if it has no leading or * trailing white space. */ public String trim(){ int len = value.length; int st = 0; char[] val = value; /* avoid getfield opcode */
/** * Compares two strings lexicographically. * The comparison is based on the Unicode value of each character in * the strings. The character sequence represented by this * {@code String} object is compared lexicographically to the * character sequence represented by the argument string. The result is * a negative integer if this {@code String} object * lexicographically precedes the argument string. The result is a * positive integer if this {@code String} object lexicographically * follows the argument string. The result is zero if the strings * are equal; {@code compareTo} returns {@code 0} exactly when * the {@link #equals(Object)} method would return {@code true}. * <p> * This is the definition of lexicographic ordering. If two strings are * different, then either they have different characters at some index * that is a valid index for both strings, or their lengths are different, * or both. If they have different characters at one or more index * positions, let <i>k</i> be the smallest such index; then the string * whose character at position <i>k</i> has the smaller value, as * determined by using the < operator, lexicographically precedes the * other string. In this case, {@code compareTo} returns the * difference of the two character values at position {@code k} in * the two string -- that is, the value: * <blockquote><pre> * this.charAt(k)-anotherString.charAt(k) * </pre></blockquote> * If there is no index position at which they differ, then the shorter * string lexicographically precedes the longer string. In this case, * {@code compareTo} returns the difference of the lengths of the * strings -- that is, the value: * <blockquote><pre> * this.length()-anotherString.length() * </pre></blockquote> * * @param anotherString the {@code String} to be compared. * @return the value {@code 0} if the argument string is equal to * this string; a value less than {@code 0} if this string * is lexicographically less than the string argument; and a * value greater than {@code 0} if this string is * lexicographically greater than the string argument. */ /** * 1. 比较字符串大小,因为String实现了Comparable<String>接口,所有重写了compareTo方法 * 2. 返回int类型,正数为大,负数为小,基于字符的ASSIC码比较 */ publicintcompareTo(String anotherString){ int len1 = value.length; int len2 = anotherString.value.length; int lim = Math.min(len1, len2); //获取长度比较小的字符串长度 char v1[] = value; char v2[] = anotherString.value;
int k = 0; while (k < lim) { //当前索引小于两个字符串中长度较小的字符串长度时,循环继续 char c1 = v1[k]; char c2 = v2[k]; if (c1 != c2) { return c1 - c2; //从前向后遍历,有一个字符不相同,返回差值 } k++; } return len1 - len2; //如果遍历结束,都相同,比较两个字符串长度 }
/** * Returns the length of this string. * The length is equal to the number of <a href="Character.html#unicode">Unicode * code units</a> in the string. * 返回字符串的长度,长度等于字符串中的Unicode代码单元的数目(UTF-16的代码单元的数目) * * @return the length of the sequence of characters represented by this * object. */
/** * Returns the number of Unicode code points in the specified text * range of this {@code String}. The text range begins at the * specified {@code beginIndex} and extends to the * {@code char} at index {@code endIndex - 1}. Thus the * length (in {@code char}s) of the text range is * {@code endIndex-beginIndex}. Unpaired surrogates within * the text range count as one code point each. * * @param beginIndex the index to the first {@code char} of * the text range. * @param endIndex the index after the last {@code char} of * the text range. * @return the number of Unicode code points in the specified text * range * @exception IndexOutOfBoundsException if the * {@code beginIndex} is negative, or {@code endIndex} * is larger than the length of this {@code String}, or * {@code beginIndex} is larger than {@code endIndex}. * @since 1.5 * 可以使用该方法返回字符串的准确长度(相对于length方法) */ publicintcodePointCount(int beginIndex, int endIndex){ if (beginIndex < 0 || endIndex > value.length || beginIndex > endIndex) { thrownew IndexOutOfBoundsException(); } return Character.codePointCountImpl(value, beginIndex, endIndex - beginIndex); }