java.lang.String源码阅读笔记
来源:互联网 发布:科密xc 55a数据库安装 编辑:程序博客网 时间:2024/05/16 23:54
是一个不可继承类final
一、实现接口
Serializable、Comparable<String>、CharSequence。
二、成员变量
一个字符常量数组value、一个int的哈希码
三、成员方法
//因为是new一个空字符串,所以直接重用空字符串的字符数组 public String() { this.value = "".value; } //通过字符串构造 //复制参数的字符串的value数组和哈希码,所以在newString前已经有一个字符串存在 public String(String original) { this.value = original.value; this.hash = original.hash; } //通过字符数组构造 //复制一份字符数组给value public String(char value[]) { this.value = Arrays.copyOf(value, value.length); } //通过字符数组的子数组构造 //在参数calue数组中从offset索引位开始截取count位给先数组 public String(char value[], int offset, int count) { if (offset < 0) { throw new StringIndexOutOfBoundsException(offset); } if (count <= 0) { if (count < 0) { throw new StringIndexOutOfBoundsException(count); } if (offset <= value.length) { this.value = "".value; return; } } // 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); } //通过unicode的整形数组来构造字符串 public String(int[] codePoints, int offset, int count) { if (offset < 0) { throw new StringIndexOutOfBoundsException(offset); } if (count <= 0) { if (count < 0) { throw new StringIndexOutOfBoundsException(count); } if (offset <= codePoints.length) { this.value = "".value; return; } } // Note: offset or count might be near -1>>>1. if (offset > codePoints.length - count) { throw new StringIndexOutOfBoundsException(offset + count); } final int end = offset + count; // 第一步计算字符数组需要的长度 int n = count; for (int i = offset; i < end; i++) { int c = codePoints[i]; //判断这个unicode是否属于2字节即1个字符,如果属于则不用扩展字符数组,如果这个unicode代表4个字节即两个字符,则需要扩展字符数组长度。这里可以查阅以下unicode的编码方式。 if (Character.isBmpCodePoint(c)) continue; else if (Character.isValidCodePoint(c)) n++; else throw new IllegalArgumentException(Integer.toString(c)); } // 第二步分配字符数组空间并赋值 final char[] v = new char[n]; for (int i = offset, j = 0; i < end; i++, j++) { int c = codePoints[i]; if (Character.isBmpCodePoint(c)) v[j] = (char)c; else Character.toSurrogates(c, v, j++); } this.value = v; } //ascii码数组的子数组转字符构造,已经废弃 public String(byte ascii[], int hibyte, int offset, int count) {} //ascii码数组转字符构造,已经废弃 public String(byte ascii[], int hibyte) {} //私有方法,提供ascii码数组构造String的边界检查方法 private static void checkBounds(byte[] bytes, int offset, int length) { if (length < 0) throw new StringIndexOutOfBoundsException(length); if (offset < 0) throw new StringIndexOutOfBoundsException(offset); if (offset > bytes.length - length) throw new StringIndexOutOfBoundsException(offset + length); } //通过使用指定的字符集解码指定的 byte 子数组,构造一个新的 String。新 String 的长度是一个字符集函数,因此可能不等于子数组的长度。 public String(byte bytes[], int offset, int length, String charsetName) throws UnsupportedEncodingException { if (charsetName == null) throw new NullPointerException("charsetName"); checkBounds(bytes, offset, length); this.value = StringCoding.decode(charsetName, bytes, offset, length); } //同上,此方法总是使用此字符集的默认替代字符串替代错误输入 public String(byte bytes[], int offset, int length, Charset charset) { if (charset == null) throw new NullPointerException("charset"); checkBounds(bytes, offset, length); this.value = StringCoding.decode(charset, bytes, offset, length); } //同上 public String(byte bytes[], String charsetName) throws UnsupportedEncodingException { this(bytes, 0, bytes.length, charsetName); } //同上 public String(byte bytes[], Charset charset) { this(bytes, 0, bytes.length, charset); } //通过使用平台的默认字符集解码指定的 byte 子数组,构造一个新的 String。新 String 的长度是字符集的函数,因此可能不等于该子数组的长度。 public String(byte bytes[], int offset, int length) { checkBounds(bytes, offset, length); this.value = StringCoding.decode(bytes, offset, length); } //同上 public String(byte bytes[]) { this(bytes, 0, bytes.length); } //通过StringBuffer构造,需要加锁防止脏数据 public String(StringBuffer buffer) { synchronized(buffer) { this.value = Arrays.copyOf(buffer.getValue(), buffer.length()); } } //通过StringBuilder构造 public String(StringBuilder builder) { this.value = Arrays.copyOf(builder.getValue(), builder.length()); } //这是包内访问权限的构造器,暂时不支持share是false,在之前的构造器,都是复制一份字符数组,而这里是直接传递引用,这样子性能好,但是破坏了数组的不可变性 String(char[] value, boolean share) { // assert share : "unshared not supported"; this.value = value; } //返回字符串长度 public int length() { return value.length; } //判断字符串长度是否为0 public boolean isEmpty() { return value.length == 0; } //返回字符串中某个序列的字符,返回字符数组中的值 public char charAt(int index) { if ((index < 0) || (index >= value.length)) { throw new StringIndexOutOfBoundsException(index); } return value[index]; } //看完Character再返回来补充-- public int codePointAt(int index) { if ((index < 0) || (index >= value.length)) { throw new StringIndexOutOfBoundsException(index); } return Character.codePointAtImpl(value, index, value.length); } //看完Character再返回来补充-- public int codePointBefore(int index) { int i = index - 1; if ((i < 0) || (i >= value.length)) { throw new StringIndexOutOfBoundsException(index); } return Character.codePointBeforeImpl(value, index, 0); } //待定 public int codePointCount(int beginIndex, int endIndex) { if (beginIndex < 0 || endIndex > value.length || beginIndex > endIndex) { throw new IndexOutOfBoundsException(); } return Character.codePointCountImpl(value, beginIndex, endIndex - beginIndex); } //待定 public int offsetByCodePoints(int index, int codePointOffset) { if (index < 0 || index > value.length) { throw new IndexOutOfBoundsException(); } return Character.offsetByCodePointsImpl(value, 0, value.length, index, codePointOffset); } //包内访问权限,将value数组从0到length复制到目标数组 void getChars(char dst[], int dstBegin) { System.arraycopy(value, 0, dst, dstBegin, value.length); } //将字符从此字符串复制到目标字符数组。 public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) { if (srcBegin < 0) { throw new StringIndexOutOfBoundsException(srcBegin); } if (srcEnd > value.length) { throw new StringIndexOutOfBoundsException(srcEnd); } if (srcBegin > srcEnd) { throw new StringIndexOutOfBoundsException(srcEnd - srcBegin); } System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin); } //已经被废弃 public void getBytes(int srcBegin, int srcEnd, byte dst[], int dstBegin) {} //使用指定的字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。 public byte[] getBytes(String charsetName) throws UnsupportedEncodingException { if (charsetName == null) throw new NullPointerException(); return StringCoding.encode(charsetName, value, 0, value.length); } //同上,用于代替错误输入 public byte[] getBytes(Charset charset) { if (charset == null) throw new NullPointerException(); return StringCoding.encode(charset, value, 0, value.length); } //使用平台的默认字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。 public byte[] getBytes() { return StringCoding.encode(value, 0, value.length); } //将此字符串与指定的对象比较。当且仅当该参数不为 null,并且是与此对象表示相同字符序列的 String 对象时,结果才为 true。 //判断是否相同引用 if (this == anObject) { return true; } //判断是否是String的实例,或者String子类的实例 if (anObject instanceof 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]) return false; i++; } return true; } } return false; } //判断字符序列是否相同 public boolean contentEquals(StringBuffer sb) { return contentEquals((CharSequence)sb); } //判断字符序列是否相同 private boolean nonSyncContentEquals(AbstractStringBuilder sb) { char v1[] = value; char v2[] = sb.getValue(); int n = v1.length; if (n != sb.length()) { return false; } for (int i = 0; i < n; i++) { if (v1[i] != v2[i]) { return false; } } return true; } //判断字符序列是否相同 public boolean contentEquals(CharSequence cs) { // 判断是StringBuffer还是StringBuilder类型的实例,但是不管什么类型,最终都是转换成StringBuilder来进行判断 if (cs instanceof AbstractStringBuilder) { //StringBuffer不是线程安全的所以要加同步锁 if (cs instanceof StringBuffer) { synchronized(cs) { return nonSyncContentEquals((AbstractStringBuilder)cs); } } else { return nonSyncContentEquals((AbstractStringBuilder)cs); } } // 如果实例是String类型 if (cs instanceof String) { return equals(cs); } // 如果实例只是一般的CharSequence char v1[] = value; int n = v1.length; if (n != cs.length()) { return false; } for (int i = 0; i < n; i++) { if (v1[i] != cs.charAt(i)) { return false; } } return true; } //判断忽略大小写后是否相等 public boolean equalsIgnoreCase(String anotherString) { //是否引用同一个对象,如果不是需要判断长度,是否为空,是否匹配 return (this == anotherString) ? true : (anotherString != null) && (anotherString.value.length == value.length) && regionMatches(true, 0, anotherString, 0, value.length); } //实现Comparable接口 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; } //一个内部类对象,一个对 String 对象进行排序的 Comparator,作用与 compareToIgnoreCase 相同。此比较器是可序列化的。 public static final Comparator<String> CASE_INSENSITIVE_ORDER = new CaseInsensitiveComparator(); //内部类的实现,继承了Comparator接口,和序列化接口,至于为什么要转换成大写又转换成小写,是因为Georgian字母表中的字母不能被转换成大写 private static class CaseInsensitiveComparator implements Comparator<String>, java.io.Serializable { // use serialVersionUID from JDK 1.2.2 for interoperability private static final long serialVersionUID = 8575799808933029326L; //覆盖compara的方法 public int compare(String s1, String s2) { int n1 = s1.length(); int n2 = s2.length(); int min = Math.min(n1, n2); for (int i = 0; i < min; i++) { char c1 = s1.charAt(i); char c2 = s2.charAt(i); if (c1 != c2) { c1 = Character.toUpperCase(c1); c2 = Character.toUpperCase(c2); if (c1 != c2) { c1 = Character.toLowerCase(c1); c2 = Character.toLowerCase(c2); if (c1 != c2) { // No overflow because of numeric promotion return c1 - c2; } } } } return n1 - n2; } //返回这个比较器的实例 private Object readResolve() { return CASE_INSENSITIVE_ORDER; } } //不区分大小写比较序列大小 public int compareToIgnoreCase(String str) { return CASE_INSENSITIVE_ORDER.compare(this, str); } //比较两个字符串的子串是否相等 public boolean regionMatches(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)) { return false; } while (len-- > 0) { if (ta[to++] != pa[po++]) { return false; } } return true; } //是否区分大小写的比较两个字符串的子串 public boolean regionMatches(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)) { return false; } 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; } } return false; } return true; } //判断字符串从toffset序列位是否以prefix为开头 public boolean startsWith(String prefix, int toffset) {} //调用上面的方法,从0位开始。 public boolean startsWith(String prefix) {} //判断是否以suffix为结束 public boolean endsWith(String suffix) { return startsWith(suffix, value.length - suffix.value.length); } //计算哈希码 public int hashCode() { int h = hash; if (h == 0 && value.length > 0) { char val[] = value; for (int i = 0; i < value.length; i++) { h = 31 * h + val[i]; } hash = h; } return h; } //返回指定字符在此字符串中第一次出现处的索引。 public int indexOf(int ch) { return indexOf(ch, 0); } // public int indexOf(int ch, int fromIndex) { final int max = value.length; if (fromIndex < 0) { fromIndex = 0; } else if (fromIndex >= max) { 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); } } private int indexOfSupplementary(int ch, int fromIndex) { if (Character.isValidCodePoint(ch)) { final char[] value = this.value; final char hi = Character.highSurrogate(ch); final char lo = Character.lowSurrogate(ch); final int max = value.length - 1; for (int i = fromIndex; i < max; i++) { if (value[i] == hi && value[i + 1] == lo) { return i; } } } return -1; } public int lastIndexOf(int ch) { return lastIndexOf(ch, value.length - 1); } public int lastIndexOf(int ch, int fromIndex) { 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; int i = Math.min(fromIndex, value.length - 1); for (; i >= 0; i--) { if (value[i] == ch) { return i; } } return -1; } else { return lastIndexOfSupplementary(ch, fromIndex); } } private int lastIndexOfSupplementary(int ch, int fromIndex) { if (Character.isValidCodePoint(ch)) { final char[] value = this.value; char hi = Character.highSurrogate(ch); char lo = Character.lowSurrogate(ch); int i = Math.min(fromIndex, value.length - 2); for (; i >= 0; i--) { if (value[i] == hi && value[i + 1] == lo) { return i; } } } return -1; }
阅读全文
0 0
- java.lang.String源码阅读笔记
- java源码阅读-java.lang.String(01)
- java.lang之java.lang.String 源码阅读及分析
- 源码阅读笔记:java.lang.Object
- java StringBuilder、stringbuffer、string 源码阅读笔记
- String源码阅读笔记
- JAVA源码阅读--String
- Java源码---java.lang.String
- java String 源码阅读笔记以及Unicode的学习
- java.lang包阅读笔记
- jdk源码(java.lang.String)
- JDK源码-java.lang.String
- java+String源码阅读1
- java String源码阅读2
- Java源码阅读之String
- Java源码阅读-String类
- java源码阅读系列-String
- Java.lang.String API笔记
- 51nod 1384 全排列
- DDD理论学习系列(11)-- 工厂
- jQuery使用ajaxSubmit()提交表单示例
- poj 1679 次小生成树
- 个人笔记2
- java.lang.String源码阅读笔记
- React Native 轻松集成分享功能(Android 篇)
- while循环求人数、增长额、年份
- 机房重构—DataGridView控件的使用
- POJ
- linux性能分析
- 微信网页授权--Java发开
- springmvc和easyui使用ajax前台后台互传数据,假删除提示警告问题。
- java集合面试题