Java源码阅读之String(终)
2018-01-05 16:39
351 查看
Java源码阅读之String(终)
最后一篇介绍String 源码的博客。/** *根据所传递的regex字符串分割当前对象,limit控制匹配分割次数 *如果limit为正值则最多匹配limit-1次,形成limit个子字符串 *如果limit为非正值则尽可能多次匹配 */ public String[] split(String regex, int limit) { char ch = 0; //如果regex是单字符串且这个字符不是".$|()[{^?*+\\"其中之一 //或者regex是双字符串,第一个字符是反斜杠且第二个不是ascii数字或ascii字母。 if (((regex.value.length == 1 && ".$|()[{^?*+\\".indexOf(ch = regex.charAt(0)) == -1) || (regex.length() == 2 && regex.charAt(0) == '\\' && (((ch = regex.charAt(1))-'0')|('9'-ch)) < 0 && ((ch-'a')|('z'-ch)) < 0 && ((ch-'A')|('Z'-ch)) < 0)) && (ch < Character.MIN_HIGH_SURROGATE || ch > Character.MAX_LOW_SURROGATE)) { int off = 0; int next = 0; boolean limited = limit > 0; ArrayList<String> list = new ArrayList<>(); while ((next = indexOf(ch, off)) != -1) { //依次进行匹配,并判断是否超出limit限制 if (!limited || list.size() < limit - 1) { list.add(substring(off, next)); off = next + 1; } else { //最后一个子字符串全部加入序列中 list.add(substring(off, value.length)); off = value.length; break; } } //如果一次都没有匹配到,直接将当前对象放入一个数组返回 if (off == 0) return new String[]{this}; //添加剩余的部分 if (!limited || list.size() < limit) list.add(substring(off, value.length)); //构造结果返回 int resultSize = list.size(); if (limit == 0) { while (resultSize > 0 && list.get(resultSize - 1).length() == 0) { resultSize--; } } String[] result = new String[resultSize]; return list.subList(0, resultSize).toArray(result); } //如果不是上面判断的,直接调用正则匹配的分割字符串 return Pattern.compile(regex).split(this, limit); } /** *从头开始分割当前对象,尽可能多的分割 */ public String[] split(String regex) { return split(regex, 0); } /** *连接字符串,至少要有两个参数,可以有多个参数 */ public static String join(CharSequence delimiter, CharSequence... elements) { Objects.requireNonNull(delimiter); Objects.requireNonNull(elements); //构建StringJoiner对象并将后面的参数拼接到对先后面 StringJoiner joiner = new StringJoiner(delimiter); for (CharSequence cs: elements) { joiner.add(cs); } return joiner.toString(); } /** *连接字符串,第一个参数为被连接的字符串,第二个参数为连接的字符串序列 */ public static String join(CharSequence delimiter, Iterable<? extends CharSequence> elements) { Objects.requireNonNull(delimiter); Objects.requireNonNull(elements); //构建StringJoiner对象并将后面的参数拼接到对先后面 StringJoiner joiner = new StringJoiner(delimiter); for (CharSequence cs: elements) { joiner.add(cs); } return joiner.toString(); } /** *使用给定的Locale的规则将此String中的所有字符转换为小写。 *大小写映射基于Character类指定的Unicode标准版本。 *由于大小写映射并不总是1:1字符映射,因此生成的字符串可能与原始字符串的长度不同。 */ public String toLowerCase(Locale locale) { if (locale == null) { throw new NullPointerException(); } int firstUpper; final int len = value.length; /* 检查有没有字符需要进行更改 */ scan: { for (firstUpper = 0 ; firstUpper < len; ) { char c = value[firstUpper]; if ((c >= Character.MIN_HIGH_SURROGATE) && (c <= Character.MAX_HIGH_SURROGATE)) { int supplChar = codePointAt(firstUpper); if (supplChar != Character.toLowerCase(supplChar)) { break scan; } firstUpper += Character.charCount(supplChar); } else { if (c != Character.toLowerCase(c)) { break scan; } firstUpper++; } } return this; } char[] result = new char[len]; int resultOffset = 0; /* 结果可能会增长,所以i + resultOffset是结果中的写入位置 */ /*只需复制前几个lowerCase字符。*/ System.arraycopy(value, 0, result, 0, firstUpper); String lang = locale.getLanguage(); boolean localeDependent = (lang == "tr" || lang == "az" || lang == "lt"); char[] lowerCharArray; int lowerChar; int srcChar; int srcCount; for (int i = firstUpper; i < len; i += srcCount) { srcChar = (int)value[i]; if ((char)srcChar >= Character.MIN_HIGH_SURROGATE && (char)srcChar <= Character.MAX_HIGH_SURROGATE) { srcChar = codePointAt(i); srcCount = Character.charCount(srcChar); } else { srcCount = 1; } if (localeDependent || srcChar == '\u03A3' || // 希腊大写字母∑ srcChar == '\u0130') { // 拉丁文大写字母i lowerChar = ConditionalSpecialCasing.toLowerCaseEx(this, i, locale); } else { lowerChar = Character.toLowerCase(srcChar); } if ((lowerChar == Character.ERROR) || (lowerChar >= Character.MIN_SUPPLEMENTARY_CODE_POINT)) { if (lowerChar == Character.ERROR) { lowerCharArray = ConditionalSpecialCasing.toLowerCaseCharArray(this, i, locale); } else if (srcCount == 2) { resultOffset += Character.toChars(lowerChar, result, i + resultOffset) - srcCount; continue; } else { lowerCharArray = Character.toChars(lowerChar); } /* 如果结果需要增长 */ int mapLen = lowerCharArray.length; if (mapLen > srcCount) { char[] result2 = new char[result.length + mapLen - srcCount]; System.arraycopy(result, 0, result2, 0, i + resultOffset); result = result2; } for (int x = 0; x < mapLen; ++x) { result[i + resultOffset + x] = lowerCharArray[x]; } resultOffset += (mapLen - srcCount); } else { result[i + resultOffset] = (char)lowerChar; } } return new String(result, 0, len + resultOffset); } /*以默认的方式对字母进行小写转化*/ public String toLowerCase() { return toLowerCase(Locale.getDefault()); } /** *使用给定的Locale的规则将此String中的所有字符转换为大写。 *大小写映射基于Character类指定的Unicode标准版本。 *由于大小写映射并不总是1:1字符映射,因此生成的字符串可能与原始字符串的长度不同。 */ public String toUpperCase(Locale locale) { if (locale == null) { throw new NullPointerException(); } int firstLower; final int len = value.length; /*现在检查是否有任何需要更改的字符。*/ scan: { for (firstLower = 0 ; firstLower < len; ) { int c = (int)value[firstLower]; int srcCount; if ((c >= Character.MIN_HIGH_SURROGATE) && (c <= Character.MAX_HIGH_SURROGATE)) { c = codePointAt(firstLower); srcCount = Character.charCount(c); } else { srcCount = 1; } int upperCaseChar = Character.toUpperCaseEx(c); if ((upperCaseChar == Character.ERROR) || (c != upperCaseChar)) { break scan; } firstLower += srcCount; } return this; } /*结果可能会增长,所以i + resultOffset是结果中的写入位置*/ int resultOffset = 0; char[] result = new char[len]; /*可能会增长*/ /*只需复制前几个大写字母。*/ System.arraycopy(value, 0, result, 0, firstLower); String lang = locale.getLanguage(); boolean localeDependent = (lang == "tr" || lang == "az" || lang == "lt"); char[] upperCharArray; int upperChar; int srcChar; int srcCount; for (int i = firstLower; i < len; i += srcCount) { srcChar = (int)value[i]; if ((char)srcChar >= Character.MIN_HIGH_SURROGATE && (char)srcChar <= Character.MAX_HIGH_SURROGATE) { srcChar = codePointAt(i); srcCount = Character.charCount(srcChar); } else { srcCount = 1; } if (localeDependent) { upperChar = ConditionalSpecialCasing.toUpperCaseEx(this, i, locale); } else { upperChar = Character.toUpperCaseEx(srcChar); } if ((upperChar == Character.ERROR) || (upperChar >= Character.MIN_SUPPLEMENTARY_CODE_POINT)) { if (upperChar == Character.ERROR) { if (localeDependent) { upperCharArray = ConditionalSpecialCasing.toUpperCaseCharArray(this, i, locale); } else { upperCharArray = Character.toUpperCaseCharArray(srcChar); } } else if (srcCount == 2) { resultOffset += Character.toChars(upperChar, result, i + resultOffset) - srcCount; continue; } else { upperCharArray = Character.toChars(upperChar); } /*如果结果需要增长*/ int mapLen = upperCharArray.length; if (mapLen > srcCount) { char[] result2 = new char[result.length + mapLen - srcCount]; System.arraycopy(result, 0, result2, 0, i + resultOffset); result = result2; } for (int x = 0; x < mapLen; ++x) { result[i + resultOffset + x] = upperCharArray[x]; } resultOffset += (mapLen - srcCount); } else { result[i + resultOffset] = (char)upperChar; } } return new String(result, 0, len + resultOffset); } /*以默认的规则方式对字符串中的字母进行大写转换*/ public String toUpperCase() { return toUpperCase(Locale.getDefault()); } /*删除字符串的前后空格*/ public String trim() { int len = value.length; int st = 0; char[] val = value; /*如果前面是空格就st自增,如果不是空格结束循环记录空格的所到位置*/ while ((st < len) && (val[st] <= ' ')) { st++; } /*如果后面是空格就st自增,如果不是空格结束循环记录空格的所到位置*/ while ((st < len) && (val[len - 1] <= ' ')) { len--; } /*将中间不是空格的部分切割出来*/ return ((st > 0) || (len < value.length)) ? substring(st, len) : this; } //这个不用说 public String toString() { return this; } //将当前对象转化为一个char数组,将当前对象的value数组复制一份返回 public char[] toCharArray() { //由于类初始化顺序问题,无法使用Arrays.copyOf进行复制 char result[] = new char[value.length]; System.arraycopy(value, 0, result, 0, value.length); return result; } //以相应的格式将当前对象格式化 public static String format(String format, Object... args) { return new Formatter().format(format, args).toString(); } //将传入的对象以字符串的形式输出 public static String valueOf(Object obj) { return (obj == null) ? "null" : obj.toString(); } //将传入的char数组转换为String对象 public static String valueOf(char data[]) { return new String(data); } //将传入的char数组转换为String对象,转化范围从offset到offset+count public static String valueOf(char data[], int offset, int count) { return new String(data, offset, count); } //将传入的char数组转换为String对象,转化范围从offset到offset+count public static String copyValueOf(char data[], int offset, int count) { return new String(data, offset, count); } //将传入的char数组转换为String对象 public static String copyValueOf(char data[]) { return new String(data); } //将传入的boolean值转换为String对象 public static String valueOf(boolean b) { return b ? "true" : "false"; } //将传入的char值转换为String对象 public static String valueOf(char c) { char data[] = {c}; return new String(data, true); } //将传入的int值转换为String对象 public static String valueOf(int i) { return Integer.toString(i); } //将传入的long值转换为String对象 public static String valueOf(long l) { return Long.toString(l); } //将传入的float值转换为String对象 public static String valueOf(float f) { return Float.toString(f); } //将传入的double值转换为String对象 public static String valueOf(double d) { return Double.toString(d); } /** *本地方法,将当前对象从JVM堆中转移到方法区的字符串池里面 *如果字符串池中已经有和当前对象值相等的对象存在则抛弃堆中的对象 *将栈中的reference指向和当前对象值相同的字符串池中的对象 *如果字符串池中不存在和当前对象值相等的对象,则将当前对象移动到字符串池中 */ public native String intern();
相关文章推荐
- 阅读Java String源码遇到的问题
- java.lang.String源码阅读笔记
- java.lang之java.lang.String 源码阅读及分析
- java源码阅读-java.lang.String(01)
- java.lang.String源码阅读笔记
- java+String源码阅读1
- Java源码阅读之String(3)
- JAVA源码阅读--String
- Java源码阅读之String(4)
- Java源码阅读之String
- Java源码阅读之StringBuidler
- Java源码阅读之String(2)
- java String源码阅读2
- java String 源码阅读笔记以及Unicode的学习
- JDK源码阅读——java.lang.Runable
- Java,String,compareTo方法的源码理解
- 干货:阅读跟踪 Java 源码的几个小技巧!
- Java源码阅读-LinkedList
- JDK源码阅读之二-----String
- 如何阅读Java源码