Java字符串:String使用详解及源码分析

来源:互联网 发布:途虎养车在淘宝有店吗 编辑:程序博客网 时间:2024/05/17 06:35

1 使用方法

  String类型的字符串是不可变字符串,提供了较多操作API。

public final class String    implements java.io.Serializable, Comparable<String>, CharSequence {}

  String可以序列化,可以使用compareTo比较字符串。

1.1 方法介绍

  String提供了的API主要如下:

public char    charAt(int index) //index位置的字符public int    compareTo(String anotherString) //按字典顺序比较两个字符串public String    concat(String str) //拼接字符串public boolean    contains(CharSequence s) //是否包含spublic boolean    contentEquals(StringBuffer sb) //比较当前String和cs是否相同public boolean    contentEquals(CharSequence cs) //同上public static String    copyValueOf(char[] data, int offset, int count) //返回从offset开始的count个字符组成的字符串Stringpublic boolean    endsWith(String suffix) //是否以suffix结尾public boolean    equals(Object anObject) //比较字符串public static String    format(String format, Object[] args) //将args格式化为formatpublic int    hashCode() //hash codepublic int    indexOf(int ch) //第一次出现ch所在的下标public int    indexOf(int ch, int fromIndex)public int    indexOf(String str) //第一次出现str的下标public int    indexOf(String str, int fromIndex)public int    lastIndexOf(int ch) //最后一次出现ch的下标public int    lastIndexOf(int ch, int fromIndex)public int    lastIndexOf(String str) //租后一次出现str的下标public int    lastIndexOf(String str, int fromIndex)public int    length() //长度public boolean    matches(String regex) //正则匹配public int    offsetByCodePoints(int index, int codePointOffset)public boolean    regionMatches(int toffset, String other, int ooffset, int len) //比较指定子串public boolean    regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len)public String    replace(char oldChar, char newChar) //替换oldChar为newCharpublic String    replace(CharSequence target, CharSequence replacement) //替换public String    replaceAll(String regex, String replacement)public String    replaceFirst(String regex, String replacement)public boolean    startsWith(String prefix, int toffset) //从toffset开始是否以prefix开头public boolean    startsWith(String prefix)public CharSequence    subSequence(int beginIndex, int endIndex) //获取子串public String    substring(int beginIndex)public String    substring(int beginIndex, int endIndex)public char[]    toCharArray()public String    toLowerCase(Locale locale) //转为小写字母public String    toLowerCase()public String    toString()public String    toUpperCase(Locale locale) //转为大写字母public String    toUpperCase()public String    trim()public static String    valueOf(Object obj) //转换为stringpublic void    getBytes(int srcBegin, int srcEnd, byte[] dst, int dstBegin) //获取byte数组public byte[]    getBytes(String charsetName)public byte[]    getBytes(Charset charset)public byte[]    getBytes()public void    getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)public boolean    isEmpty() //判空

1.2 使用示例

public void testString () {    String myStr = new String("MYSTR");    //myStr的长度    System.out.println("myStr的长度为: " + myStr.length());    //myStr判空    System.out.println("myStr是否为空: " + myStr.isEmpty());    //获取指定位置的字符    System.out.println("myStr的第4个字符为: " + myStr.charAt(3));    //将myStr转换为数组    char [] chars = myStr.toCharArray();    try {        printChars(chars);    } catch (Exception e) {        System.out.println("myStr转换数组失败!");    }    System.out.println();    //格式化字符串    System.out.println("格式化myStr: " + String.format("%s-%d-%b", myStr, 3, true));    //追加字符串    System.out.println("myStr追加字符ING!: " + myStr.concat("ING!"));    //拼接的字符串为一个新的对象,不影响原有字符串    System.out.println("myStr的字符串为: " + myStr);    //获取子串    System.out.println("myStr第2到5个字符的子串为: " + myStr.substring(1,5));    //替换    System.out.println("替换Y为y: " + myStr.replace("Y", "y"));    //比较    System.out.println("myStr字符串和\"MySTR\"是否相等: " + myStr.compareTo("MySTR"));    //忽略大小写比较    System.out.println("myStr字符串和\"MySTR\"是否相等: " + myStr.compareToIgnoreCase("MySTR"));    //获取字符的index    System.out.println("\"ST\"在myStr中第一次出现的位置: " + myStr.indexOf("ST"));    //获取Unicode编码    System.out.printf("%s0x%x", "第一个字符M的Unicode编码为: ",myStr.codePointAt(0));}/** * 打印字符数组 * @param chars * @throws NullPointerException */public void printChars(char[] chars) throws Exception {    if (chars == null) {        throw new NullPointerException();    }    for (int i = 0; i < chars.length; i++) {        System.out.printf("char[%d]=%c ", i, chars[i]);    }}

  运行结果如下:

myStr的长度为: 5myStr是否为空: falsemyStr的第4个字符为: Tchar[0]=M char[1]=Y char[2]=S char[3]=T char[4]=R格式化myStr: MYSTR-3-truemyStr追加字符ING!: MYSTRING!myStr的字符串为: MYSTRmyStr第25个字符的子串为: YSTR替换Y为y: MySTRmyStr字符串和"MySTR"是否相等: -32myStr字符串和"MySTR"是否相等: 0"ST"在myStr中第一次出现的位置: 2第一个字符M的Unicode编码为: 0x4d

2 源码分析

  String的字符串是不可变的,拼接替换等操作都会返回新的String实例,不会影响原有的字符串。

/** The value is used for character storage. */private final char value[]; //final类型

2.1构造函数

  String包含的构造函数很多,主要区别是是否初始化和初始化方式。下面列举两个代表行的例子。

/** * 申请一个空的String * Initializes a newly created {@code String} object so that it represents * an empty character sequence.  Note that use of this constructor is * unnecessary since Strings are immutable. */public String() {    this.value = new char[0];}/** * Allocates a new {@code String} that contains characters from a subarray * of the character array argument. The {@code offset} argument is the * index of the first character of the subarray and the {@code count} * argument specifies the length of the subarray. The contents of the * subarray are copied; subsequent modification of the character array does * not affect the newly created string. * * @param  value *         Array that is the source of characters * * @param  offset *         The initial offset * * @param  count *         The length * * @throws  IndexOutOfBoundsException *          If the {@code offset} and {@code count} arguments index *          characters outside the bounds of the {@code value} array */public String(char value[], int offset, int count) {    if (offset < 0) {        throw new StringIndexOutOfBoundsException(offset);    }    if (count < 0) {        throw new StringIndexOutOfBoundsException(count);    }    // Note: offset or count might be near -1>>>1.    if (offset > value.length - count) {        throw new StringIndexOutOfBoundsException(offset + count);    }    this.value = Arrays.copyOfRange(value, offset, offset+count);}

2.2 compareTo方法

/** * 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 &lt; 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. */public int compareTo(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;}

2.3 concat方法

/** * Concatenates the specified string to the end of this string. * <p> * If the length of the argument string is {@code 0}, then this * {@code String} object is returned. Otherwise, a * {@code String} object is returned that represents a character * sequence that is the concatenation of the character sequence * represented by this {@code String} object and the character * sequence represented by the argument string.<p> * Examples: * <blockquote><pre> * "cares".concat("s") returns "caress" * "to".concat("get").concat("her") returns "together" * </pre></blockquote> * * @param   str   the {@code String} that is concatenated to the end *                of this {@code String}. * @return  a string that represents the concatenation of this object's *          characters followed by the string argument's characters. */public String concat(String str) {    int otherLen = str.length();    if (otherLen == 0) { //判空        return this;    }    int len = value.length;    char buf[] = Arrays.copyOf(value, len + otherLen); //获取原字符串的字符数组    str.getChars(buf, len); //将str存到buf的尾部    return new String(buf, true); //返回新String}

2.4 replace方法

  replace方法有很多重载方法,下面只分析其中一种。

/** * Returns a string resulting from replacing all occurrences of * {@code oldChar} in this string with {@code newChar}. * <p> * If the character {@code oldChar} does not occur in the * character sequence represented by this {@code String} object, * then a reference to this {@code String} object is returned. * Otherwise, a {@code String} object is returned that * represents a character sequence identical to the character sequence * represented by this {@code String} object, except that every * occurrence of {@code oldChar} is replaced by an occurrence * of {@code newChar}. * <p> * Examples: * <blockquote><pre> * "mesquite in your cellar".replace('e', 'o') *         returns "mosquito in your collar" * "the war of baronets".replace('r', 'y') *         returns "the way of bayonets" * "sparring with a purple porpoise".replace('p', 't') *         returns "starring with a turtle tortoise" * "JonL".replace('q', 'x') returns "JonL" (no change) * </pre></blockquote> * * @param   oldChar   the old character. * @param   newChar   the new character. * @return  a string derived from this string by replacing every *          occurrence of {@code oldChar} with {@code newChar}. */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;}

参考:

[1] http://blog.csdn.net/mazhimazh/article/details/17715677
[2] http://www.cnblogs.com/skywang12345/p/string01.html

0 0