下载地址请点击我
资源好不好自己看
package java.lang;
import java.io.ObjectStreamField;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Formatter;
import java.util.Locale;
import java.util.Objects;
import java.util.StringJoiner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
/**
*{@code String}类表示字符串。全部
*Java程序中的字符串文本,例如{@code“abc”},是
*作为此类的实例实现。
*<p>
*字符串是常量;它们的值在
*被创造出来。字符串缓冲区支持可变字符串。
*因为字符串对象是不可变的,所以可以共享它们。例如:
*<blockquote><pre>
*String str=“abc”;
*</pre></blockquote><p>
*相当于:
*<blockquote><pre>
*char data[]={'a','b','c'};
*String str=新字符串(数据);
*</pre></blockquote><p>
*下面是一些有关如何使用字符串的更多示例:
*<blockquote><pre>
* 系统输出打印(“abc”);
*String cde=“cde”;
* 系统输出打印(“abc”+cde);
*字符串c=“abc”。子字符串(2,3);
*字符串d=cde.子串(1,2);
*</pre></blockquote>
*<p>
*类{@code String}包含用于检查
*序列的单个字符,用于比较字符串,用于
*搜索字符串、提取子字符串和创建
*将所有字符转换为大写或
*小写。案例映射基于Unicode标准版本
*由{@链接指定java.lang.Character语言字符类。
*<p>
*Java语言为字符串提供了特殊的支持
*连接运算符(+),用于转换
*字符串的其他对象。实现了字符串连接
*通过{@code StringBuilder}(或{@code StringBuffer})
*类及其{@code append}方法。
*字符串转换通过方法实现
*{@code toString},由{@code Object}和
*由Java中的所有类继承。有关
*字符串连接和转换,请参见Gosling、Joy和Steele,
*<i>Java语言规范</i>。
*
*<p>除非另有说明,否则将<tt>null</tt>参数传递给构造函数
*或类中的方法将导致{@link NullPointerException}
*扔了。
*
*<p>A{@code String}表示UTF-16格式的字符串
*其中,<em>补充字符</em>由<em>替代项表示
*对</em>(请参见<a ref='字符.html#unicode“>Unicode码
*的{@code Character}类中的字符表示</a>
*更多信息)。
*索引值引用{@code char}代码单元,因此
*字符在{@code String}中使用两个位置。
*<p>类{@code String}提供处理
*Unicode代码点(即字符),以及
*处理Unicode代码单元(即{@code char}值)。
*
*@作者李博因顿
*@作者亚瑟·范霍夫
*@作者马丁·布赫霍尔茨
*@作者乌尔夫·齐比斯
*@看java.lang.ObjectétoString()
*@看java.lang.StringBuffer语言
*@看java.lang.StringBuilder语言
*@看java.nio.charset文件.字符集
*@JDK1.0之后
*/
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];
/** Cache the hash code for the string */
private int hash; // Default to 0
/** use serialVersionUID from JDK 1.0.2 for interoperability */
private static final long serialVersionUID = -6849794470754667710L;
/**
*类字符串是序列化流协议中的特殊大小写。
*
*字符串实例根据
*<a href={@docRoot}/。/platform/serialization/spec/输出.html">
*对象序列化规范,第6.2节,“流元素”</a>
*/
private static final ObjectStreamField[] serialPersistentFields =
new ObjectStreamField[0];
/**
*初始化新创建的{@code String}对象,使其表示
*一个空字符序列。注意,这个构造函数的用法是
*不需要,因为字符串是不可变的。
*/
public String() {
this.value = "".value;
}
/**
*初始化新创建的{@code String}对象,使其表示
*与参数相同的字符序列;换句话说
*新创建的字符串是参数字符串的副本。除非
*需要{@code original}的显式副本,使用此构造函数是
*不需要,因为字符串是不可变的。
*
*@param原件
*{@code字符串}
*/
public String(String original) {
this.value = original.value;
this.hash = original.hash;
}
/**
*分配一个新的{@code String},以便它表示
*字符数组参数中当前包含的字符。这个
*复制字符数组的内容;随后修改
*字符数组不影响新创建的字符串。
*
*@param值
*字符串的初始值
*/
public String(char value[]) {
this.value = Arrays.copyOf(value, value.length);
}
/**
*分配新的{@code String},其中包含子数组中的字符
*字符数组参数的。{@code offset}参数是
*子数组的第一个字符的索引和{@code count}
*参数指定子数组的长度。的内容
*子数组被复制;字符数组的后续修改
*不影响新创建的字符串。
*
*@param值
*作为字符源的数组
*
*@param偏移量
*初始偏移量
*
*@param计数
*长度
*
*@抛出IndexOutboundsException
*如果{@code offset}和{@code count}参数索引
*{@code value}数组边界之外的字符
*/
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;
}
}
//注意:偏移量或计数可能接近-1>>>1。
if (offset > value.length - count) {
throw new StringIndexOutOfBoundsException(offset + count);
}
this.value = Arrays.copyOfRange(value, offset, offset+count);
}
/**
*分配新的{@code String},其中包含子数组中的字符
*的字符.html#unicode“>Unicode代码点</a>数组
*争论。{@code offset}参数是第一个代码的索引
*子数组的点和{@code count}参数指定
*子阵列的长度。子数组的内容转换为
*{@code char}s;对{@code int}数组的后续修改不会
*影响新创建的字符串。
*
*@param码位
*作为Unicode代码点源的数组
*
*@param偏移量
*初始偏移量
*
*@param计数
*长度
*
*@抛出IllegalArgumentException
*如果在{@code中发现任何无效的Unicode代码点
*码位}
*
*@抛出IndexOutboundsException
*如果{@code offset}和{@code count}参数索引
*{@code codePoints}数组边界之外的字符
*
*@从1.5开始
*/
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;
}
}
//注意:偏移量或计数可能接近-1>>>1。
if (offset > codePoints.length - count) {
throw new StringIndexOutOfBoundsException(offset + count);
}
final int end = offset + count;
//步骤1:计算char[]的精确大小
int n = count;
for (int i = offset; i < end; i++) {
int c = codePoints[i];
if (Character.isBmpCodePoint(c))
continue;
else if (Character.isValidCodePoint(c))
n++;
else throw new IllegalArgumentException(Integer.toString(c));
}
//传递2:分配并填写char[]
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;
}
/**
*分配从数组的子数组构造的新{@code String}
*8位整数值。
*
*<p>参数{@code offset}是
*子数组,{@code count}参数指定
*子阵。
*
*<p>子数组中的每个{@code byte}都转换为{@code char}作为
*在上述方法中指定。
*
*@已弃用此方法无法将字节正确转换为字符。
*从JDK 1.1开始,首选的方法是通过
*{@code String}接受{@link的构造函数
* java.nio.charset文件.Charset}、Charset名称或使用平台的
*默认字符集。
*
*@param ascii码
*要转换为字符的字节
*
*@param希比
*每个16位Unicode代码单元的前8位
*
*@param偏移量
*初始偏移量
*@param计数
*长度
*
*@抛出IndexOutboundsException
*如果{@code offset}或{@code count}参数无效
*
*@见字符串(byte[],int)
*@请参阅字符串(byte[],int,int,java.lang.String语言)
*@请参阅字符串(byte[],int,int,java.nio.charset文件.字符集)
*@请参阅字符串(byte[],int,int)
*@见字符串(字节[],java.lang.String语言)
*@见字符串(字节[],java.nio.charset文件.字符集)
*@见字符串(字节[])
*/
@Deprecated
public String(byte ascii[], int hibyte, int offset, int count) {
checkBounds(ascii, offset, count);
char value[] = new char[count];
if (hibyte == 0) {
for (int i = count; i-- > 0;) {
value[i] = (char)(ascii[i + offset] & 0xff);
}
} else {
hibyte <<= 8;
for (int i = count; i-- > 0;) {
value[i] = (char)(hibyte | (ascii[i + offset] & 0xff));
}
}
this.value = value;
}
/**
*分配新的{@code String}包含从
*一个8位整数值数组。中的每个字符
*结果字符串由相应的组件构造
*字节数组中的b</i>,以便:
*
*<blockquote><pre>
*<b><i>c</i></b>=(字符)(hibyte&0xff)<;<;8)
*|(<b><i>b</i></b>&0xff)
*</pre></blockquote>
*
*@已弃用此方法无法将字节正确转换为
*角色。从JDK 1.1开始,首选的方法是通过
*{@code String}接受{@link的构造函数
* java.nio.charset文件.Charset}、Charset名称或使用平台的
*默认字符集。
*
*@param ascii码
*要转换为字符的字节
*
*@param希比
*每个16位Unicode代码单元的前8位
*
*@请参阅字符串(byte[],int,int,java.lang.String语言)
*@请参阅字符串(byte[],int,int,java.nio.charset文件.字符集)
*@请参阅字符串(byte[],int,int)
*@见字符串(字节[],java.lang.String语言)
*@见字符串(字节[],java.nio.charset文件.字符集)
*@见字符串(字节[])
*/
@Deprecated
public String(byte ascii[], int hibyte) {
this(ascii, hibyte, 0, ascii.length);
}
/* Common private utility method used to bounds check the byte array
*和字符串使用的请求偏移量和长度值(字节[],…)
*施工人员。
*/
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);
}
/**
*通过解码
*使用指定字符集的字节。新{@code String}的长度
*是字符集的函数,因此可能不等于长度
*子阵的。
*
*<p>给定字节无效时此构造函数的行为
*在给定的字符集中未指定。{@链接
* java.nio.charset文件.CharsetDecoder}类应在更多控件时使用
*需要解码过程。
*
*@param字节
*要解码为字符的字节
*
*@param偏移量
*要解码的第一个字节的索引
*
*@param长度
*要解码的字节数
*@param字符集名称
*支持的{@linkplain的名称java.nio.charset文件.字符集
*字符集}
*
*@throws不支持编码异常
*如果不支持命名字符集
*
*@抛出IndexOutboundsException
*如果{@code offset}和{@code length}参数索引
*{@code bytes}数组界限之外的字符
*
*@从JDK1.1开始
*/
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);
}
/**
*通过解码
*使用指定{@linkplain的字节java.nio.charset文件.Charset字符集}。
*新{@code String}的长度是字符集的函数,并且
*因此可能不等于子阵的长度。
*
*<p>此方法总是替换格式错误的输入和不可映射的字符
*使用此字符集的默认替换字符串的序列。{@链接
* java.nio.charset文件.CharsetDecoder}类应在更多控件时使用
*需要解码过程。
*
*@param字节
*要解码为字符的字节
*
*@param偏移量
*要解码的第一个字节的索引
*
*@param长度
*要解码的字节数
*
*@param字符集
*{@link平原java.nio.charset文件.Charset Charset}用于
*解码{@code bytes}
*
*@抛出IndexOutboundsException
*如果{@code offset}和{@code length}参数索引
*{@code bytes}数组界限之外的字符
*
*@从1.6开始
*/
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);
}
/**
*通过解码指定的字节数组来构造新的{@code String}
*使用指定的{@linkplainjava.nio.charset文件.Charset字符集}。这个
*新{@code String}的长度是字符集的函数,因此
*不能等于字节数组的长度。
*
*<p>给定字节无效时此构造函数的行为
*在给定的字符集中未指定。{@链接
* java.nio.charset文件.CharsetDecoder}类应在更多控件时使用
*需要解码过程。
*
*@param字节
*要解码为字符的字节
*
*@param字符集名称
*支持的{@linkplain的名称java.nio.charset文件.字符集
*字符集}
*
*@throws不支持编码异常
*如果不支持命名字符集
*
*@从JDK1.1开始
*/
public String(byte bytes[], String charsetName)
throws UnsupportedEncodingException {
this(bytes, 0, bytes.length, charsetName);
}
/**
*通过解码指定的
*使用指定{@linkplain的字节java.nio.charset文件.Charset字符集}。
*新{@code String}的长度是字符集的函数,并且
*因此可能不等于字节数组的长度。
*
*<p>此方法总是替换格式错误的输入和不可映射的字符
*使用此字符集的默认替换字符串的序列。{@链接
* java.nio.charset文件.CharsetDecoder}类应在更多控件时使用
*需要解码过程。
*
*@param字节
*要解码为字符的字节
*
*@param字符集
*{@link平原java.nio.charset文件.Charset Charset}用于
*解码{@code bytes}
*
*@从1.6开始
*/
public String(byte bytes[], Charset charset) {
this(bytes, 0, bytes.length, charset);
}
/**
*通过解码
*使用平台默认字符集的字节。新的长度
*{@code String}是字符集的函数,因此可能不相等
*子阵列的长度。
*
*<p>给定字节无效时此构造函数的行为
*在默认字符集中未指定。{@链接
* java.nio.charset文件.CharsetDecoder}类应在更多控件时使用
*需要解码过程。
*
*@param字节
*要解码为字符的字节
*
*@param偏移量
*要解码的第一个字节的索引
*
*@param长度
*要解码的字节数
*
*@抛出IndexOutboundsException
*如果{@code offset}和{@code length}参数索引
*{@code bytes}数组界限之外的字符
*
*@从JDK1.1开始
*/
public String(byte bytes[], int offset, int length) {
checkBounds(bytes, offset, length);
this.value = StringCoding.decode(bytes, offset, length);
}
/**
*通过解码指定的字节数组来构造新的{@code String}
*使用平台的默认字符集。新{@代码的长度
*String}是字符集的函数,因此可能不等于
*字节数组的长度。
*
*<p>给定字节无效时此构造函数的行为
*在默认字符集中未指定。{@链接
* java.nio.charset文件.CharsetDecoder}类应在更多控件时使用
*需要解码过程。
*
*@param字节
*要解码为字符的字节
*
*@从JDK1.1开始
*/
public String(byte bytes[]) {
this(bytes, 0, bytes.length);
}
/**
*分配包含字符序列的新字符串
*当前包含在字符串缓冲区参数中。的内容
*复制字符串缓冲区;随后修改字符串缓冲区
*不影响新创建的字符串。
*
*@param缓冲区
*{@code StringBuffer}
*/
public String(StringBuffer buffer) {
synchronized(buffer) {
this.value = Arrays.copyOf(buffer.getValue(), buffer.length());
}
}
/**
*分配包含字符序列的新字符串
*当前包含在字符串生成器参数中。的内容
*字符串生成器被复制;字符串生成器的后续修改
*不影响新创建的字符串。
*
*<p>提供此构造函数是为了方便迁移到{@code
*字符串生成器}。通过{@代码从字符串生成器获取字符串
*toString}方法可能运行得更快,通常是首选方法。
*
*@param生成器
*{@code StringBuilder}
*
*@从1.5开始
*/
public String(StringBuilder builder) {
this.value = Arrays.copyOf(builder.getValue(), builder.length());
}
/*
*为速度共享值数组的包专用构造函数。
*此构造函数应始终使用share==true调用。
*需要一个单独的构造函数,因为我们已经有一个public
*String(char[])生成给定char[]副本的构造函数。
*/
String(char[] value, boolean share) {
//assert share:“不支持非共享”;
this.value = value;
}
/**
*返回此字符串的长度。
*长度等于字符.html#unicode“>Unicode码
*字符串中的代码单位</a>。
*
*@return这个字符序列的长度
*反对。
*/
public int length() {
return value.length;
}
/**
*返回{@code true}如果且仅当{@link#length()}是{@code 0}。
*
*@return{@code true}如果{@link#length()}是{@code 0},否则
*{@code假}
*
*@从1.6开始
*/
public boolean isEmpty() {
return value.length == 0;
}
/**
*返回位于
*指定的索引。索引的范围从{@code 0}到
*{@code length()-1}。序列的第一个{@code char}值
*位于索引{@code 0},下一个位于索引{@code 1},
*等等,比如数组索引。
*
*<p>如果索引指定的{@code char}值是
*<a href=”字符.html#unicode“>代理项</a>,代理项
*返回值。
*
*@param index{@code char}值的索引。
*@返回此字符串的指定索引处的{@code char}值。
*第一个{@code char}值位于索引{@code 0}。
*如果{@code index}
*参数为负数或不小于
*弦。
*/
public char charAt(int index) {
if ((index < 0) || (index >= value.length)) {
throw new StringIndexOutOfBoundsException(index);
}
return value[index];
}
/**
*返回指定位置的字符(Unicode代码点)
*索引。索引引用{@code char}值
*(Unicode代码单位),范围从{@code 0}到
*{@link#length()}{@code-1}。
*
*<p>如果给定索引处指定的{@code char}值
*在高代理项范围内,以下索引较少
*比这个{@code String}的长度,以及
*{@code char}以下索引处的值位于
*低代理项范围,然后是补充代码点
*将返回对应于此代理项对的。否则,
*返回给定索引处的{@code char}值。
*
*@param索引{@code char}值的索引
*@返回字符在
*{@code索引}
*如果{@code index}
*参数为负数或不小于
*弦。
*@从1.5开始
*/
public int codePointAt(int index) {
if ((index < 0) || (index >= value.length)) {
throw new StringIndexOutOfBoundsException(index);
}
return Character.codePointAtImpl(value, index, value.length);
}
/**
*返回指定的
*索引。索引引用{@code char}值
*(Unicode代码单位),范围从{@code 1}到{@link
*字符序列长度。
*
*<p>如果{@code(index-1)}处的{@code char}值
*在低代理项范围内,{@code(index-2)}不
*负,并且{@code(索引)处的{@code char}值-
*2)}在高代理项范围内,则
*代理项对的补充码位值为
*回来了。如果{@code char}值位于{@code index-
*1}是未配对的低代理项或高代理项
*返回代理项值。
*
*@param index应该返回的代码点后面的索引
*@返回给定索引之前的Unicode码位值。
*如果{@code index}
*参数小于1或大于长度
*这根绳子的。
*@从1.5开始
*/
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);
}
/**
*返回指定文本中Unicode代码点的数目
*此{@code String}的范围。文本范围从
*指定{@code beginIndex},并扩展到
*{@code char}位于索引{@code endIndex-1}。因此
*文本范围的长度(以{@code char}s为单位)为
*{@code-endIndex-beginIndex}。内的未配对代理
*每个文本区域计为一个代码点。
*
*@param beginIndex第一个{@code char}的索引
*文本范围。
*@param endIndex最后一个{@code char}之后的索引
*文本范围。
*@返回指定文本中Unicode代码点的数目
*范围
*@exception indexOutboundsException如果
*{@code beginIndex}为负数,