一、String类的不可变性
源码:
public final class String//final修饰类,不可继承
private final char value[];//String类实际返回值为final修饰的char数组,其对象内容
1、测试数组char数组能否代替字符串
public static void main(String[] args) {
String str = "abc";
char[] ch = {'a','b','c'};
System.out.println(str);
System.out.println(ch);
}
结果:可替代
abc
abc
2、测试String类是否可变
public static void main(String[] args) {
String str = "abc";
String t1 = str;
str = "ab";
String t2 =str;
//假如String可变,t1=t2,反之,t1!=t2
System.out.println(t1==t2);
}
public static void main(String[] args) {
StringBuilder str = new StringBuilder("abc");
StringBuilder t1 = str;
StringBuilder t2 =str.append("d");
//假如String可变,t1=t2,反之,t1!=t2
System.out.println(t1==t2);
}
结果:不可变
false
true
二、String类常用构造
源码:
public String() {
this.value = "".value;
}
public String(String original) {
this.value = original.value;
this.hash = original.hash;
}
public String(char value[]) {
this.value = Arrays.copyOf(value, value.length);
}
1、为何采用Arrays.copyof而非直接用this.value=value
传递的value为可变对象,将this.value指向它时,则this.value失去不可变性,而Arrays.copyof采用浅复制,保留了this.value的不可变性
2、源码复制过来一堆错?
。。。。源码中很多东西,你是没有使用权限的
三、String类常用方法
源码:
1、length()获取字符串长度
//其实就是获取char数组元素个数
public int length() {
return value.length;
}
2、isEmpty()判断是否为空
//假如字符串为null,则无法使用
public boolean isEmpty() {
return value.length == 0;
}
3、charAt(int i)获取指定位置字符
//返回字符数组指定元素
public char charAt(int index) {
if ((index < 0) || (index >= value.length)) {
throw new StringIndexOutOfBoundsException(index);
}
return value[index];
}
4、equals(Object o )比较是否与指定对象内容相同
//如果是字符串,则挨个比较字符数组内容是否都相同
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
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;
}
*equalsIgnoreCase(String str)忽略大小写比较
//这里不是很明白,为何要比较两次,全大写或全小写,在我看都能实现目的
if (ignoreCase) {
char u1 = Character.toUpperCase(c1);
char u2 = Character.toUpperCase(c2);
if (u1 == u2) {
continue;
}
if (Character.toLowerCase(u1) == Character.toLowerCase(u2)) {
continue;
}
}
5、compareTo(String s)按字典顺序比较字符串
//长度不一样,返回长度差,字符不一样,返回字符顺序差,完全一致,返回0
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;
}
6、startsWith(String s,int i) 判断字符是否从指定位置以指定字符串开始
public boolean startsWith(String prefix, int toffset) {
char ta[] = value;
int to = toffset;
char pa[] = prefix.value;
int po = 0;
int pc = prefix.value.length;
// Note: toffset might be near -1>>>1.
if ((toffset < 0) || (toffset > value.length - pc)) {
return false;
}
while (--pc >= 0) {
if (ta[to++] != pa[po++]) {
return false;
}
}
return true;
}
7、subString(int from,int end)按指定位置截取字符串
//其实就是按位复制字符数组
public String substring(int beginIndex, int endIndex) {
if (beginIndex < 0) {
throw new StringIndexOutOfBoundsException(beginIndex);
}
if (endIndex > value.length) {
throw new StringIndexOutOfBoundsException(endIndex);
}
int subLen = endIndex - beginIndex;
if (subLen < 0) {
throw new StringIndexOutOfBoundsException(subLen);
}
return ((beginIndex == 0) && (endIndex == value.length)) ? this
: new String(value, beginIndex, subLen);
}
8、replace(char old,char new)将字符串中全部old字符替换为new
public String replace(char oldChar, char newChar) {
if (oldChar != newChar) {
int len = value.length;
int i = -1;
char[] val = value; /* avoid getfield opcode */
//如果不存在想被替换字符,则 i =len
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;
}
9、contains(String str)字符串中是否还有str子字符串
//借用indexOf,如果存在则得到正数
public boolean contains(CharSequence s) {
return indexOf(s.toString()) > -1;
}
10、matches(String regex)字符串是否满足正则匹配
public boolean matches(String regex) {
return Pattern.matches(regex, this);
}
11、replaceAll(String regex,String ele)按正则替换
public String replaceAll(String regex, String replacement) {
return Pattern.compile(regex).matcher(this).replaceAll(replacement);
}
12、split(String regex,int limit)按正则拆分字符串,获取指定个数的字符串数组
public String[] split(String regex, int limit) {
char ch = 0;
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 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 { // last one
//assert (list.size() == limit - 1);
list.add(substring(off, value.length));
off = value.length;
break;
}
}
// If no match was found, return this
if (off == 0)
return new String[]{this};
// Add remaining segment
if (!limited || list.size() < limit)
list.add(substring(off, value.length));
// Construct result
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);
}
13、toCharArray()将字符串还原为字符数组
public char[] toCharArray() {
//类初始化顺序导致该方法无法使用
// Cannot use Arrays.copyOf because of class initialization order issues
char result[] = new char[value.length];
System.arraycopy(value, 0, result, 0, value.length);
return result;
}
14、valueOf(Object o)
//如果字符数组或字符则用构造方法,如果是布尔类型,则返回true or false,如果是其他基本数据类型则用包装类的toString,
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
public static String valueOf(char c) {
char data[] = {c};
return new String(data, true);
}
public static String valueOf(int i) {
return Integer.toString(i);
}
public static String valueOf(boolean b) {
return b ? "true" : "false";
}
14、format(String format ,Object...params)格式化字符串
public static String format(String format, Object... args) {
return new Formatter().format(format, args).toString();
}
四、正则表达式
字符
c 字符c
\unnnn, \xnn,\0n, \0nn, \0nnn 带有十六或八进制值的代码单元
\0n 八进制0n代表的字符(0<=n<=7)
\0nn 八进制0nn代表的字符(0<=n<=7)
\0mnn 八进制0mnn代表的字符(0<=m<=3,0<=n<=7)
\xnn 十六进制 0xnn所代表的字符
\uhhhh 十六进制 0xhhhh所代表的字符
\t, \n, \r, \f,\a, \e控制字符,依次是制表符,换行符,回车符,换页符,报警符和转义符
\cc 控制字符中出现的相应字符c
字符类
[C1C2. . .] C1、C2……中的任何字符。Ci可以是字符,字符范围(C1-C2)或者字符类。
[^. . .] 字符类的补集
[ . . .&& . . .] 两个字符类的交集
预定义字符类
. 除行终止符外的任何字符(如果DOTALL标志置位,则表示任何字符)
\d 数字[0-9]
\D 非数字[^0-9]
\s 空白字符[\t\n\r\f\x0B]
\S 非空白字符
\w 单词字符[a-zA-Z0-9_]
\W 非单词字符
\p{name} 一个指定的字符类,见表12-9
\P{name} 指定字符类的补集
边界匹配符
^ 和$ 输入的开头和结尾(在多行模式(multilinemode)下是行的开头和结尾)
\b 单词边界
\B 非单词边界
\A 输入的开头
\z 输入的结尾
\Z 除最后行终止符之外的输入结尾
\G 上个匹配的结尾
量词
X? 可选的X(即X可能出现,也可能不出现)
X* X,可以重复0次或多次
X+ X,可以重复1次或多次
X{n} X{n,}X{n,m} X重复n次,至少重复n次,重复n到m次
量词后缀(表达式所有量词都要加)
? 设默认(贪婪)匹配为reluctant(勉强)匹配
+ 设默认(贪婪)匹配为possessive(强制)匹配
贪婪匹配:正则表达式一般趋向于最大长度匹配,也就是所谓的贪婪匹配。如上面使用模式p匹配字符串str,结果就是匹配到:abcaxc(ab*c)。
非贪婪匹配:就是匹配到结果就好,就少的匹配字符。如上面使用模式p匹配字符串str,结果就是匹配到:abc(ab*c)。
。z~~z~~ 深夜1.11完稿。。。。。。。睡觉走起。。。