String字符串
1.介绍
1.1String就是一个字符串序列的对象,它是一个final类,没有子类。底层采用char[]数组来存储内容。使用count表示长度。它是一个固定的对象值,一旦初始化后,大小和长度就不能改变了。
1.2主要方法有一下几种类型:构造方法、比较方法、获取对应位置上的值、追加内容的方法、拆分方法、替换方法、替换方法
a)构造方法
a1) 空字符串
String();
a2) 通过charset编码类型的bytes数组构造字符串
String(byte[] bytes, Charset charset);
a3) 通过使用指定的 charset 解码指定的 byte 子数组,构造一个新的 String
String(byte[]bytes, int offset, int length, Charset charset)
a4) 通过字符数组构造一个字符串
String(char[] value)
a5) 通过字符串对象构造一个新字符串
String(String original)
a6) 通过StringBuffer构造一个字符串
String(StringBuffer buffer)
a7) 通过StringBuilder构造一个字符串
String(StringBuilder builder)
b) 比较方法
b1) 比较字符串大小的方法
int compareTo(String str);
b2)忽略字符大小 比较字符串大小的方法
intcompareToIgnoreCase(String str)
说明:
返回值 大于0、等于0、小于0,分别代表当前字符串字典顺序大于,等于,小于str字符串
b3)与Object比较是否内容相同
booleanequals(Object anObject)
b4)与StringBuffer比较是否内容相同
boolean contentEquals(StringBuffer sb)
b5)与CharSequence比较是否内容相同
booleancontentEquals(CharSequence cs)
b6) 与字符串anotherString忽略大小写的比较内容是否相同
boolean equalsIgnoreCase(StringanotherString)
c) 包含关系
c1) 测试此字符串是否以指定的前缀开始。
booleanstartsWith(String prefix);
c2) 测试此字符串从指定索引开始的子字符串是否以指定前缀开始。
boolean startsWith(Stringprefix,int toffset);
prefix - 前缀。
toffset - 在此字符串中开始查找的位置。
测试此字符串从指定索引开始的子字符串是否以指定前缀开始
c3) 测试此字符串是否以指定的后缀结束
boolean endsWith(String suffix);
suffix
- 后缀。
d)获取内容方法
d1) 获取指定索引处的 char 值
char charAt(int index);
d2) 返回指定索引处的字符(Unicode 代码点)
int codePointAt(int index)
d3) 返回指定索引之前的字符(Unicode代码点)
int codePointBefore(intindex)
d4) 使用给定的Charset编码到 byte 序列
byte[] getBytes(Charsetcharset);
d5) 使用给定的String编码到 byte 序列
byte[] getBytes(String charsetName)
d6) 返回指定字符在此字符串中第一次出现处的索引
int indexOf(int ch);
在此对象表示的字符序列中第一次出现该字符的索引;如果未出现该字符,则返回-1
d7)
返回指定字符在此字符串中从特定位置开始后第一次出现处的索引
intindexOf(int ch,int fromIndex)
d8)返回指定子字符串在此字符串中第一次出现处的索引
int indexOf(String str);
e)拆分子串的方法
e1)从指定下标拆分
String substring(intbeginIndex);
返回一个新的字符串,它是此字符串的一个子字符串。该子字符串从指定索引处的字符开始,直到此字符串末尾
e2)指定歧视和结束位置的拆分,返回子字符串
String substring(int beginIndex,intendIndex)
返回一个新字符串,它是此字符串的一个子字符串。该子字符串从指定的 beginIndex 处开始,直到索引 endIndex - 1 处的字符
e3) CharSequence subSequence(intbeginIndex,int endIndex)
返回一个新的字符序列,它是此序列的一个子序列. 该子字符串从指定的 beginIndex 处开始,直到索引 endIndex - 1 处的字符
e4) 根据给定正则表达式的匹配拆分此字符串
String[] split(String regex);
留意,如果跟定的字符串里有转义字符,要正确表示转义字符,不然拆分结果可能不正确。
e5)根据正则表达式及最多拆分的次数来拆分字符串
String[] split(Stringregex,int limit)
regex - 定界正则表达式
limit – 拆分子串的阈值
f)替换方法
f1)字符替换方法
String replace(charoldChar, char newChar)
参数:
oldChar : 原字符。
newChar : 新字符。
返回:
将此字符串中的所有 oldChar 替代为 newChar,返回新串
f2)字符队列替换
String replace(CharSequencetarget,CharSequence replacement)
参数:
target :要被替换的 char 值序列
replacement :char 值的替换序列
返回: 所得 String
f3)使用给定的 字符串替换此字符串所有匹配给定的正则表达式的子字符串。
replaceAll(Stringregex, String replacement)
参数:
regex- 用来匹配此字符串的正则表达式
replacement- 用来替换每个匹配项的字符串
返回:
所得 String
g)转变方法
g1) 字符串转换成字符数组
char[] toCharArray();
g2)将字符串全部转成小写
StringtoLowerCase()
g3) 将字符串全部转成大写
String toUpperCase()
g4)清除字符串里的空字符
String trim()
h) )追加内容的
h1) 将指定字符串连接到此字符串的结尾
String concat(String str);
i)其它方法
i1) 字符串是否为空
boolean isEmpty()
i2)字符串的长度
int length()
2.主要方法源码介绍
a)构造方法举例
String提供了多种多样的构造方法,其实实现原理都一样,判断给的参数的合法性,然后被内容转化成char[]数组,赋值给成员变量value,把长度获取到赋值给成员变量count。所以我们挑选String(char[]data, int start, int length)来熟悉String的构造函数
public String(char[] data, int start, int length) {
//判断合法性,起始下表和长度都要大于零,长度不能超过从起始下表到data末尾下表值
if (start >= 0&& 0 <= length && length <= data.length - start) {
offset = 0;
value = newchar[length];
//赋值长度
count = length;
//复制字符数组内容
System.arraycopy(data, start, value, 0, count);
} else {
throw newStringIndexOutOfBoundsException();
}
}
b)字符串比较方法
字符串的比较方法较多,主要有比较大小,比较是否相等的,以及忽略大写比较的,其实实现原理大同小异,核心就是逐个字符比较大小而已。说以我们只看下int compareTo(String anotherString)实现。
实现原理: 基本从0开始,比较到两 个串里较短的长度处。如果中间不相等就已经比出来结果。如果一直比完还没有必出结果。就说明两个串至少有一个和一个的部分相同,直接比较两个串的长度,串相对较长的一个较大,长度一样说明两串相等。
public int compareTo(String string) {
//起始位置
int o1 = offset, o2 = string.offset, result;
//结束位置以短的串为主
int end = offset + (count < string.count ? count : string.count);
char[] target = string.value;
while (o1 < end) {
if ((result = value[o1++] -target[o2++]) != 0) {
//当前字符串不相等,已经比出来结果
return result;
}
}
//一个短字符串结束还没有比出来,根据长度长度,长度长的大。
return count - string.count;
}
c. 字符串包含关系
字符串串包含方法主要有判断串是否相等、判断串是不是以特定子串开头、串是不是以特定子串结尾。
boolean startsWith(Stringprefix,int toffset). 测试此字符串从指定索引开始的子字符串是否以指定前缀开始。
实现原理:
其实先排除异常情况,prefix为空直接抛出异常;其次考虑特殊情况,toffset下标为空,返回false;其次如果字符串从toffset到尾部的长度小于prefix的长度,返回false;prefix长度为0,返回true;最后就从两个字符串的特定位置开始比较,直到比较到prefix的尾部。如果中间有字符不相等就返回 false。比较完还没有返回值,就返回true,代表包含。
public boolean startsWith(String prefix, intstart) {
returnregionMatches(start, prefix, 0, prefix.count);
}
public booleanregionMatches(int thisStart, String string, int start,
int length) {
if (string == null) {
//比较字符串为空,抛出异常
throw newNullPointerException();
}
if (start < 0 ||string.count - start < length) {
return false;
}
if (thisStart < 0|| count - thisStart < length) {
//起始位置小于零或者当前串从起始位置到尾部的长度小于待比较串长度,返回false
return false;
}
//待比较的串为空,返回true
if (length <= 0) {
return true;
}
int o1 = offset +thisStart, o2 = string.offset + start;
char[] value1 = value;
char[] value2 =string.value;
//两个串从特定位置开始比较,直到比较到string尾部结束,其中有一个字符不相等就返回false
for (int i = 0; i <length; ++i) {
if (value1[o1 + i]!= value2[o2 + i]) {
return false;
}
}
return true;
}
d)拆子字符串的方法
主要实现从字符串里拆分出想要的字符串。主要有两种类型,一种是根据拆分的位置,拆分出来一个字串Stringsubstring(int beginIndex,int endIndex);一种是根据拆分的正则表达式,拆分出一组子串出来String[] split(String regex);
d1) String substring(int beginIndex,intendIndex)
原理:如果拆分的起始位置和字符串的起始位置一样,结束位置和字符串的长度一样,直接就返回当前串就行;如果串拆分位置合法,就创建一个符合特定条件新的字符串;串拆分位置非法的话,抛出下标异常。
public String substring(int start, intend) {
if (start == 0 && end == count) {
return this;
}
if (0 <= start && start <= end && end <= count){
return new String(offset + start, end - start, value);
}
throw new StringIndexOutOfBoundsException();
}
d2) String[] split(String regex)
public String[] split(StringregularExpression) {
return split(regularExpression, 0);
}
public String[] split(StringregularExpression, int limit) {
String[] result =java.util.regex.Splitter.fastSplit(regularExpression, this, limit);
return result != null ? result : Pattern.compile(regularExpression).
split(this, limit);
}
split 其实核心就是调用Splitter类fastSplit方法,Splitter里重载了几个fastSplit方法,实现字符串的正则表达式的分割,细节的话研究这个类即可。
e)字符串的替换
字符串的替换,可以整齐替换单个字符,替换字符串,替换字符队列。以替换字符串举例,
原理:1)剔除想替换的字符串队列为空或者替换后的字符串队列为空,直接抛出空指针异常。
2)如果想替换的字符队列在原始的字符串里不存在,直接返回原始字符串
3)如果想替换的子字符串为空,相当于给原始字符串的每个字符之后追加想替换的串
4)正常情况的话,从原始字符串里开始查找想替换串的位置,找到后把替换串之前的字符串加入到结果里,再把
想替换后的字符串加入到结果里。接着从新的下标下接着查找,重复步骤四,直到最终找不到目标串存在
public String replace(CharSequence target, CharSequence replacement) {
if (target == null) {
throw new NullPointerException("target == null");
}
if (replacement == null) {
throw new NullPointerException("replacement == null");
}
String targetString = target.toString();
int matchStart = indexOf(targetString, 0);
if (matchStart == -1) {
return this;
}
String replacementString = replacement.toString();
int targetLength = targetString.length();
if (targetLength == 0) {
int resultLength = (count + 2) * replacementString.length();
StringBuilder result = new StringBuilder(resultLength);
result.append(replacementString);
for (int i = offset; i < count; ++i) {
result.append(value[i]);
result.append(replacementString);
}
return result.toString();
}
StringBuilder result = new StringBuilder(count);
int searchStart = 0;
do {
result.append(value, offset + searchStart, matchStart - searchStart);
result.append(replacementString);
searchStart = matchStart +targetLength;
} while ((matchStart = indexOf(targetString, searchStart)) != -1);
result.append(value, offset + searchStart, count - searchStart);
return result.toString();
}