JDK源码阅读-------自学笔记(三)(java.lang.String String用法和描述浅析)
一、源码特点
- final约束,使得String不能被继承,内部其他也不能被继承
- String用来表示字符串,或字符序列,序列即为数组
- 内建数组private final char value[];但是,只能创建一次,因为final限制(核心代码就是此处)
- 看源码是为了更好理解相关概念
二、常量池
- String str1 = "abc"; 形式的数据都是以内存地址的形式存入常量池
- String str2 = new String("def"); 此为创建一个新对象
- str1和str2不是同一个对象,通常比较字符串,使用equals,equals比较的是内容
三、场景
- 处理各种字符串的情况
四、内存指向
五、应用和描述
1、获取(JDK1.8版本)
根据位置获取位置上某个字符
源码:1 public char charAt(int index) {
2 if ((index < 0) || (index >= value.length)) {
3 throw new StringIndexOutOfBoundsException(index);
4 }
5 return value[index];
6 }源码分析:
1、传入的index的值小于零或者大于数组长度,抛出字符串数组越界
2、如果不是1的情况,就把index的值放入数组的位置,返回数组的值应用:
1 String demoOne = "abcd";
2 char value=demoOne.charAt(3);
3 System.out.println("3位置的值是:"+value);字符串中的包含的字符数,也就是字符串的长度
源码:1 public int length() {
2 return value.length;
3 }源码分析:
字符串数组的长度直接返回
应用:1 String demoTwo = "abcd";
2 int length = demoTwo.length();
3 System.out.println("输出字符串长度是:"+length);
- 根据字符获取该字符在字符串中位置
int indexOf(int ch, int fromIndex)
从fromIndex指定位置开始,获取ch(ch需要是ASCII值,其中a的ASCII为97)在字符串中出现的位置
源码:1 /**
2 * 从fromIndex指定位置开始,获取ch在字符串中出现的位置
3 * @param ch 字符串中出现位置
4 * @param fromIndex 从什么位置开始
5 * @return
6 */
7 public int indexOf(int ch, int fromIndex) {
8
9 // 数组长度
10 final int max = value.length;
11
12 // 小于零,返回零
13 if (fromIndex < 0) {
14 fromIndex = 0;
15
16 //与数组长度相同,返回-1
17 } else if (fromIndex >= max) {
18 // Note: fromIndex might be near -1>>>1.
19 return -1;
20 }
21
22
23 //MIN_SUPPLEMENTARY_CODE_POINT这个数代表十进制中62355,刚好是2个字节
24 //ch的值小于62355
25 if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
26 // handle most cases here (ch is a BMP code point or a
27 // negative value (invalid code point))
28
29 // 数组值放入value
30 final char[] value = this.value;
31
32 // 从开始位置遍历,找到ch的位置,返回索引
33 for (int i = fromIndex; i < max; i++) {
34 if (value[i] == ch) {
35 return i;
36 }
37 }
38 return -1;
39 } else {
40 // 从开始位置遍历,找到ch的位置,返回索引
41 return indexOfSupplementary(ch, fromIndex);
42 }
43 }
44
45
46 private int indexOfSupplementary(int ch, int fromIndex) {
47 if (Character.isValidCodePoint(ch)) {
48 final char[] value = this.value;
49 final char hi = Character.highSurrogate(ch);
50 final char lo = Character.lowSurrogate(ch);
51 final int max = value.length - 1;
52 for (int i = fromIndex; i < max; i++) {
53 if (value[i] == hi && value[i + 1] == lo) {
54 return i;
55 }
56 }
57 }
58 return -1;
59 }
60
61 public static boolean isValidCodePoint(int codePoint) {
62 // Optimized form of:
63 // codePoint >= MIN_CODE_POINT && codePoint <= MAX_CODE_POINT
64 int plane = codePoint >>> 16;
65 return plane < ((MAX_CODE_POINT + 1) >>> 16);
66 }源码分析:
1、判断开始位置的长度,小于零,返回零,等于数组长度,返回-1
2、判断字符串中出现位置是否小于62355,小于数组值放入value,从开始位置遍历,找到ch的位置,返回索引,大于,相同小于
应用:1 String demoThree = "abcdaaccbb";
2 int indexOf = demoThree.indexOf(97,2);
3 System.out.println("输出b后b有b字符串的位置是:"+indexOf);int indexOf(int ch)
返回的是ch在字符串中第一次出现的位置。
源码:1 public int indexOf(int ch) {
2 return indexOf(ch, 0);
3 }源码分析:
默认输入其实位置为0,其他跟int indexOf(int ch, int fromIndex)一样
应用:1 String demoFour = "abcdaaccbb";
2 int locationValue = demoFour.indexOf(97);
3 System.out.println("输出a的位置是:"+locationValue);int indexOf(String str, int fromIndex)
从fromIndex指定位置开始,获取str在字符串中出现的位置。
源码:1 /**
2 * 获取字符在fromIndex为零开始后的位置值
3 * @param str 输入字符串
4 * @param fromIndex 起始位置
5 * @return
6 */
7 public int indexOf(String str, int fromIndex) {
8
9 return indexOf(value, 0, value.length,
10 str.value, 0, str.value.length, fromIndex);
11 }
12
13 /**
14 * 逻辑:
15 * 1、查找首字符,匹配target的第一个字符在source内的位置,若查找到max位置还找到,则返回-1;
16 * 2、若在source匹配到了target的第一个字符,那么在依次比较srouce和target后面的字符,一直到target的末尾;
17 * 3、如果target后面的字符与source都已经匹配,则返回在source上匹配到的第一个字符的相对下标,否则返回-1。
18 *
19 *
20 * @param source 字符数据
21 * @param sourceOffset 数据源偏移
22 * @param sourceCount 统计传入字符数组的字符个数
23 * @param target 传入字符
24 * @param targetOffset 传入字符偏移量
25 * @param targetCount 传入字符的个数
26 * @param fromIndex 其实位置
27 * @return
28 */
29 static int indexOf(char[] source, int sourceOffset, int sourceCount,
30 char[] target, int targetOffset, int targetCount,
31 int fromIndex) {
32
33 // 起始位置是否大于字符串数组长度
34 if (fromIndex >= sourceCount) {
35 // 传入字符个数是否为零 是 返回传入字符个数,否则,返回-1
36 return (targetCount == 0 ? sourceCount : -1);
37 }
38
39 // 起始位置小于零,按零计算
40 if (fromIndex < 0) {
41 fromIndex = 0;
42 }
43
44 // 传入字符为零,返回起始位置值
45 if (targetCount == 0) {
46 return fromIndex;
47 }
48
49 // 查找首字符
50 char first = target[targetOffset];
51
52 // 计算出最大的首字符匹配次数
53 int max = sourceOffset + (sourceCount - targetCount);
54
55 // 遍历匹配次数,查找子字符串的第一个字符
56 for (int i = sourceOffset + fromIndex; i <= max; i++) {
57
58
59 //如果第一个字符都没有出现,则此字符串中不包含这个子字符串
60 if (source[i] != first) {
61 while (++i <= max && source[i] != first);
62 }
63
64
65
66 // 查找到第一个字符,则继续查找剩下的字符
67 if (i <= max) {
68 int j = i + 1;
69 int end = j + targetCount - 1;
70 for (int k = targetOffset + 1; j < end && source[j]
71 == target[k]; j++, k++);
72
73 if (j == end) {
74 /* Found whole string. */
75 return i - sourceOffset;
76 }
77 }
78 }
79
80 // 未找到返回-1
81 return -1;
82 }源码分析:
1、查找首字符,匹配target的第一个字符在source内的位置,若查找到max位置还找到,则返回-1;
2、若在source匹配到了target的第一个字符,那么在依次比较srouce和target后面的字符,一直到target的末尾;
3、如果target后面的字符与source都已经匹配,则返回在source上匹配到的第一个字符的相对下标,否则返回-1。应用:
1 String demoFive = "abcdaaccbb";
2 int isLocationValue = demoFive.indexOf("da",1);
3 System.out.println("从b开始输出其后a的位置是:"+isLocationValue);int lastIndexOf(int ch)
返回最后一次出现ch(ch需要是ASCII值,其中a的ASCII为97)字符的位置
源码:1 /**
2 * 最后出现位置的值
3 * @param ch 最后一次出现ch(ch需要是ASCII值,其中a的ASCII为97)字符的位置
4 * @return 位置的值
5 */
6 public int lastIndexOf(int ch) {
7 return lastIndexOf(ch, value.length - 1);
8 }
9
10
11 /**
12 * 在此对象表示的字符序列(小于等于fromIndex)中最后一次出现该字符的索引;如果在该点之前未出现该字符,则返回-1。
13 * @param ch 最后一次出现ch(ch需要是ASCII值,其中a的ASCII为97)字符的位置
14 * @param fromIndex 数组最大值的位置
15 * @return
16 */
17 public int lastIndexOf(int ch, int fromIndex) {
18
19 // ch的值不小于代表十进制中62355,刚好是2个字节
20 if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
21
22 // 赋值给字符串数组
23 final char[] value = this.value;
24
25 // 数组最大值中的较小的一个
26 int i = Math.min(fromIndex, value.length - 1);
27
28 // 遍历最大值的位置
29 for (; i >= 0; i--) {
30 if (value[i] == ch) {
31 return i;
32 }
33 }
34 return -1;
35 } else {
36 return lastIndexOfSupplementary(ch, fromIndex);
37 }
38 }
39
40 private int lastIndexOfSupplementary(int ch, int fromIndex) {
41 if (Character.isValidCodePoint(ch)) {
42 final char[] value = this.value;
43 char hi = Character.highSurrogate(ch);
44 char lo = Character.lowSurrogate(ch);
45 int i = Math.min(fromIndex, value.length - 2);
46 for (; i >= 0; i--) {
47 if (value[i] == hi && value[i + 1] == lo) {
48 return i;
49 }
50 }
51 }
52 return -1;
53 }源码分析:
在此对象表示的字符序列(小于等于fromIndex)中最后一次出现该字符的索引;如果在该点之前未出现该字符,则返回-1。
应用:1 String demoSix = "abcdaaccbb";
2 int lastIndexOfValue = demoSix.lastIndexOf(97);
3 System.out.println("a最后的位置是:" + lastIndexOfValue);
2、判断
- 字符串中是否包含某一个子串
boolean contains(str)特殊之处:indexOf(str):可以索引str第一次出现位置,如果返回-1.表示该str不在字符串中存在。所以,也可以用于对指定判断是否包含。
if(str.indexOf("mmm")!=-1)
而且该方法即可以判断,有可以获取出现的位置。
源码:1 /**
2 * 判断返回结果是不是大于-1,是就返回true,反之返回false,通过一个个字符比较得出是否包含
3 * @param s
4 * @return
5 */
6 public boolean contains(CharSequence s) {
7 return indexOf(s.toString()) > -1;
8 }
9
10 public int indexOf(String str) {
11 return indexOf(str, 0);
12 }
13
14 public int indexOf(String str, int fromIndex) {
15 return indexOf(value, 0, value.length,
16 str.value, 0, str.value.length, fromIndex);
17 }
18
19 static int indexOf(char[] source, int sourceOffset, int sourceCount,
20 char[] target, int targetOffset, int targetCount,
21 int fromIndex) {
22 if (fromIndex >= sourceCount) {
23 return (targetCount == 0 ? sourceCount : -1);
24 }
25 if (fromIndex < 0) {
26 fromIndex = 0;
27 }
28 if (targetCount == 0) {
29 return fromIndex;
30 }
31
32 char first = target[targetOffset];
33 int max = sourceOffset + (sourceCount - targetCount);
34
35 for (int i = sourceOffset + fromIndex; i <= max; i++) {
36 /* Look for first character. */
37 if (source[i] != first) {
38 while (++i <= max && source[i] != first);
39 }
40
41 /* Found first character, now look at the rest of v2 */
42 if (i <= max) {
43 int j = i + 1;
44 int end = j + targetCount - 1;
45 for (int k = targetOffset + 1; j < end && source[j]
46 == target[k]; j++, k++);
47
48 if (j == end) {
49 /* Found whole string. */
50 return i - sourceOffset;
51 }
52 }
53 }
54 return -1;
55 }源码分析:
判断返回结果是不是大于-1,是就返回true,反之返回false,通过一个个字符比较得出是否包含
应用:1 String demoSeven = "abcdaaccbb";
2
3 boolean isContains = demoSeven.contains("cab");
4
5 System.out.println("是否包含cab是:" + isContains); 字符中是否有内容
boolean isEmpty()
原理就是判断长度是否为0
源码:1 public boolean isEmpty() {
2 return value.length == 0;
3 }源码分析:
判断数组长度是否等于零,等于零,为true,不为零为false.
应用:1 String demoEight = "abcdaaccbb";
2
3 boolean empty = demoEight.isEmpty();
4
5 System.out.println(empty);- 字符串是否是以指定内容开头。
boolean startsWith(str)
字符串是否以str的字母为首
源码:
1 /**
2 * 是否是第一个字母相同
3 *
4 * @param prefix 在前面的字母
5 * @return 是否是第一个字母相同
6 */
7 public boolean startsWith(String prefix) {
8 return startsWith(prefix, 0);
9 }
10
11 /**
12 * 是否是第一个字母相同
13 *
14 * @param prefix 穿来的字符串
15 * @param toffset 默认首字符标识数字
16 * @return 返回是否是第一个字母
17 */
18 public boolean startsWith(String prefix, int toffset) {
19
20 // 数组赋值
21 char ta[] = value;
22
23 // 角标赋值
24 int to = toffset;
25
26 // 字符串数组化
27 char pa[] = prefix.value;
28
29 int po = 0;
30
31 // 传入字符串长度
32 int pc = prefix.value.length;
33
34 // 如果角标小于零或数组长度减去传入字符串长度小于零。返回false
35 if ((toffset < 0) || (toffset > value.length - pc)) {
36 return false;
37 }
38
39 // 字符串按长度遍历
40 while (--pc >= 0) {
41
42 // 数组赋值的第一个元素不等于字符串数组化的第一个元素
43 if (ta[to++] != pa[po++]) {
44 return false;
45 }
46
47 }
48 return true;
49 }源码分析:
字符串按长度遍历,数组赋值的第一个元素不等于字符串数组化的第一个元素
应用:1 String demoNine = "abcdaaccbb";
2 boolean isStartsWith = demoNine.startsWith("a");
3 System.out.println("是否以a开头" + isStartsWith); - 字符串是否是以指定内容结尾
boolean endsWith(str)
字符串是否以str的字母为结尾
源码:
1 /**
2 * 是否以某字符为结尾
3 *
4 * @param suffix 传入的结尾字符
5 * @return 是否以某字符为结尾
6 */
7 public boolean endsWith(String suffix) {
8 return startsWith(suffix, value.length - suffix.value.length);
9 }
10
11 /**
12 * 是否以某字符为结尾
13 *
14 * @param prefix
15 * @param toffset
16 * @return 是否以某字符为结尾
17 */
18 public boolean startsWith(String prefix, int toffset) {
19 char ta[] = value;
20 int to = toffset;
21 char pa[] = prefix.value;
22 int po = 0;
23 int pc = prefix.value.length;
24 // Note: toffset might be near -1>>>1.
25 if ((toffset < 0) || (toffset > value.length - pc)) {
26 return false;
27 }
28 while (--pc >= 0) {
29 if (ta[to++] != pa[po++]) {
30 return false;
31 }
32 }
33 return true;
34 }源码分析:
字符串按长度遍历,数组赋值的第一个元素不等于字符串数组化的第一个元素
应用:1 String demoTen = "abcdaaccbb";
2 boolean isEndsWith = demoTen.endsWith("b");
3 System.out.println("是否以b结尾" + isEndsWith); - 判断字符串内容是否相同。覆写了Object类中的equals方法
boolean equals(str)
判断字符串内容是否相同
源码:
1 /**
2 * 对字符串内容进行比较,每个字符比较.相同返回true,否则false
3 *
4 * @param anObject 传入的对象
5 * @return 对字符串内容进行比较是否相等
6 */
7 public boolean equals(Object anObject) {
8
9 // 传入object和当前对象相等,返回true
10 if (this == anObject) {
11 return true;
12 }
13
14 // 传入object和是否是String类型,返回true
15 if (anObject instanceof String) {
16
17 String anotherString = (String) anObject;
18 int n = value.length;
19
20 // 判断长度是否相等
21 if (n == anotherString.value.length) {
22 char v1[] = value;
23 char v2[] = anotherString.value;
24 int i = 0;
25
26 //按照数组的每一位进行比较
27 while (n-- != 0) {
28 if (v1[i] != v2[i])
29 return false;
30 i++;
31 }
32 return true;
33 }
34 }
35
36 //不是String类型,返回false
37 return false;
38 }源码分析:
对字符串内容进行比较,每个字符比较.相同返回true,否则false
应用:1 String demoEleven = "abcdaaccbb";
2 boolean isEquals = demoEleven.equals("3333");
3 System.out.println("是否相等:" + isEquals); - 判断内容是否相同,并忽略大小写
boolean equalsIgnoreCase()
忽略大小写判断字符串是否相同
源码:
1 /**
2 * 忽略大小写是否相等
3 *
4 * @param anotherString 传入字符串
5 * @return 忽略大小写是否相等
6 */
7 public boolean equalsIgnoreCase(String anotherString) {
8
9
10 // 判断跟当前字符串是否相等,相等返回true
11 return (this == anotherString) ? true
12
13 // 如果不想等,当前字符串是否不为空,长度和数组长度是否相等,同时,满足区域匹配的方法
14 : (anotherString != null)
15 && (anotherString.value.length == value.length)
16 && regionMatches(true, 0, anotherString, 0, value.length);
17 }
18
19
20 /**
21 * 区域匹配
22 * 字符串转为字符串数组,挨个元素拿出来互相比较,不想等,同时转为大写比较,不想等同时转为小写比较
23 *
24 * @param ignoreCase 是否忽略大小写(默认true)
25 * @param toffset 数组起始位置
26 * @param other 传入的字符串
27 * @param ooffset 结束的位置
28 * @param len 数组长度
29 * @return 区域匹配是否成立
30 */
31 public boolean regionMatches(boolean ignoreCase, int toffset,
32 String other, int ooffset, int len) {
33 // 数组赋值
34 char ta[] = value;
35
36 // 起始位置赋值
37 int to = toffset;
38
39 // 字符串转数组
40 char pa[] = other.value;
41
42 // 结束位置
43 int po = ooffset;
44
45 // 起始位置小于零或结束位置小于零或结束位置大于数组长度减去数组长度或传入数组长度减去数组长度小于结束位置
46 if ((ooffset < 0) || (toffset < 0)
47 || (toffset > (long) value.length - len)
48 || (ooffset > (long) other.value.length - len)) {
49 return false;
50 }
51
52 // 遍历数组
53 while (len-- > 0) {
54
55 char c1 = ta[to++];
56 char c2 = pa[po++];
57
58 // 取出第一个元素开始比较
59 if (c1 == c2) {
60 continue;
61 }
62
63 // 取出的元素不通,忽略大小写
64 if (ignoreCase) {
65
66
67 char u1 = Character.toUpperCase(c1);
68 char u2 = Character.toUpperCase(c2);
69
70 // 将取出元素转为大写继续比较
71 if (u1 == u2) {
72 continue;
73 }
74
75
76 // 转为大写不想等,再转为消歇比较
77 if (Character.toLowerCase(u1) == Character.toLowerCase(u2)) {
78 continue;
79 }
80 }
81 return false;
82 }
83 return true;
84 }源码分析:
字符串转为字符串数组,挨个元素拿出来互相比较,不想等,同时转为大写比较,不想等同时转为小写比较
应用:1 String demoTwelve = "abcdaaccbb";
2 boolean isEqualsIgnoreCase = demoTwelve.equalsIgnoreCase("ABC");
3 System.out.println("忽略大小写是否相等" + isEqualsIgnoreCase);
3、转换
- 将字符数组转成字符串
构造函数:
String(char[])
源码:1 /**
2 *
3 * 给传入的数组的内容复制放入一个新的数组中,这样传入的数组的值不会被改变,只有新建的字符串里会被改变
4 * @param value 字符串的初始值
5 */
6 public String(char value[]) {
7 this.value = Arrays.copyOf(value, value.length);
8 }
9
10
11 /**
12 * 字符串数组拷贝
13 *
14 * @param original 传入字符串数组
15 * @param newLength 传入数组长度
16 * @return 拷贝好的数组
17 */
18 public static char[] copyOf(char[] original, int newLength) {
19
20 // 创建一个新的用来拷贝的数组
21 char[] copy = new char[newLength];
22
23 // 数组的拷贝机制(arraycopy底层源码,懂原理就好)
24 // src 源数组(就是来源数组,这里指传入数组)
25 // srcPos 拷贝数组开始的位置
26 // dest 目的数组(拷贝到这个新的数组中)
27 // destPos 被拷贝数组开始的位置
28 // length 拷贝多少个字符元素
29 System.arraycopy(original, 0, copy, 0,
30 Math.min(original.length, newLength));
31 return copy;
32 }源码分析:
给传入的数组的内容复制放入一个新的数组中,这样传入的数组的值不会被改变,只有新建的字符串里会被改变
应用:1 char[] arrays={'a','b','c'};
2
3 String stringArrays= new String(arrays);
4
5 String[] split = stringArrays.split(",");
6
7
8 for (String s : split) {
9 System.out.println("new :"+s+" ");
10 }
11
12 for (char array : arrays) {
13 System.out.print("old:"+array+" ");
14 }String(char[],offset,count)
源码:1 /**
2 * 原理:给传入的数组的内容复制放入一个新的数组中,这样传入的数组的值不会被改变,只有新建的字符串里会被改变
3 * @param value 传入数组
4 * @param offset 数组角标
5 * @param count 元素个数
6 */
7 public String(char value[], int offset, int count) {
8 if (offset < 0) {
9 throw new StringIndexOutOfBoundsException(offset);
10 }
11 if (count <= 0) {
12 if (count < 0) {
13 throw new StringIndexOutOfBoundsException(count);
14 }
15 if (offset <= value.length) {
16 this.value = "".value;
17 return;
18 }
19 }
20 // Note: offset or count might be near -1>>>1.
21 if (offset > value.length - count) {
22 throw new StringIndexOutOfBoundsException(offset + count);
23 }
24
25 // 数组拷贝,同上边的
26 this.value = Arrays.copyOfRange(value, offset, offset+count);
27 }源码分析:
给传入的数组的内容复制放入一个新的数组中,这样传入的数组的值不会被改变,只有新建的字符串里会被改变(多了一个参数,控制从数组的第几个元素开始复制)
应用:1 char[] arrays={'a','b','c'};
2
3 String stringArrays= new String(arrays,1,2);
4
5 String[] split = stringArrays.split(",");
6
7
8 for (String s : split) {
9 System.out.println("new :"+s+" ");
10 }
11
12 for (char array : arrays) {
13 System.out.print("old:"+array+" ");
14 }将字符数组中的一部分转成字符串
静态方法:
static String copyValueOf(char[])
源码:1 /**
2 * 拷贝数组值
3 *
4 * @param data 传入数据
5 * @return 返回结果
6 */
7 public static String copyValueOf(char data[]) {
8 return new String(data);
9 }
10
11 /**
12 * 上边完事走这里
13 * @param value 传入数组
14 */
15 public String(char value[]) {
16 this.value = Arrays.copyOf(value, value.length);
17 }源码分析:
同String(char[])
应用:1 char[] arrays = {'a', 'b', 'c'};
2
3 String stringArrays = new String();
4
5
6 System.out.println("new :" + stringArrays.copyValueOf(arrays) + " ");
7
8
9 for (char array : arrays) {
10 System.out.print("old:" + array + " ");
11 }static String copyValueOf(char[] data, int offset, int count)
源码:1 /**
2 * 跟上边的构造方法里传多个参数一样
3 */
4 public static String copyValueOf(char data[], int offset, int count) {
5 return new String(data, offset, count);
6 }
7
8
9 /**
10 * 上边结束走这里
11 */
12 public String(char value[], int offset, int count) {
13 if (offset < 0) {
14 throw new StringIndexOutOfBoundsException(offset);
15 }
16 if (count <= 0) {
17 if (count < 0) {
18 throw new StringIndexOutOfBoundsException(count);
19 }
20 if (offset <= value.length) {
21 this.value = "".value;
22 return;
23 }
24 }
25 // Note: offset or count might be near -1>>>1.
26 if (offset > value.length - count) {
27 throw new StringIndexOutOfBoundsException(offset + count);
28 }
29 this.value = Arrays.copyOfRange(value, offset, offset+count);
30 }
31
32 }源码分析:
同String(char[],offset,count)
应用:1 char[] arrays={'a','b','c'};
2
3 String stringArrays= new String();
4
5
6
7 System.out.println("new :"+stringArrays.copyValueOf(arrays,0,2)+" ");
8
9
10 for (char array : arrays) {
11 System.out.print("old:"+array+" ");
12 }static String valueOf(char[])
将 char 数组 data 转换成字符串
源码:1 /**
2 * 返回字符串的值
3 *
4 * @param data 传入字符串数组
5 * @return 对象
6 */
7 public static String valueOf(char data[]) {
8 return new String(data);
9 }
10
11 /**
12 * 返回拷贝后的值
13 *
14 * @param value 传入字符串数组
15 */
16 public String(char value[]) {
17 this.value = Arrays.copyOf(value, value.length);
18 }源码分析:
同String(char[])
应用:1 char[] arrays = {'a', 'b', 'c'};
2
3 String stringArrays = new String();
4
5
6 System.out.println("new :" + stringArrays.valueOf(arrays) + " ");
7
8
9 for (char array : arrays) {
10 System.out.print("old:" + array + " ");
11 } - 将字符串转成字符数组
char[] toCharArray()
源码:
1 /**
2 * 字符串转化为数组
3 *
4 * @return 数组
5 */
6 public char[] toCharArray() {
7
8 // 建立一个新的数组
9 char result[] = new char[value.length];
10
11 // 把字符串拷贝进数组
12 System.arraycopy(value, 0, result, 0, value.length);
13
14 //返回数组
15 return result;
16 }源码分析:
1、建立一个新的数组
2、把字符串拷贝进数组
3、返回数组
应用:1 char[] arrays = {'a', 'b', 'c'};
2
3 String stringArrays = new String();
4
5
6 System.out.println("new :" + stringArrays.valueOf(arrays) + " ");
7
8
9 for (char array : arrays) {
10 System.out.print("old:" + array + " ");
11 } - 将字节数组转成字符串
String(byte[])
构造函数转化
源码:1 /**
2 * 将字节数组转成字符串
3 *
4 * @param value 传入的字节
5 */
6 public String(byte bytes[]) {
7 this(bytes, 0, bytes.length);
8 }
9
10 /**
11 * 构造函数传参
12 *
13 * @param bytes 传入的字节
14 * @param offset 字节起始位置
15 * @param length 字节长度
16 */
17 public String(byte bytes[], int offset, int length) {
18 //是否数组越界
19 checkBounds(bytes, offset, length);
20
21 // 审核后进行字节数组转成字符串
22 this.value = StringCoding.decode(bytes, offset, length);
23 }
24
25
26 /**
27 * 审核字节长度是否会导致数组越界
28 *
29 * @param bytes 传入的字节
30 * @param offset 字节起始位置
31 * @param length 字节长度
32 */
33 private static void checkBounds(byte[] bytes, int offset, int length) {
34
35 // 判断字节长度是否小于零
36 if (length < 0)
37 throw new StringIndexOutOfBoundsException(length);
38 // 判断字节长度是否大于零
39 if (offset < 0)
40 throw new StringIndexOutOfBoundsException(offset);
41 // 判断字节长度是否大于字节长度减去字节长度
42 if (offset > bytes.length - length)
43 throw new StringIndexOutOfBoundsException(offset + length);
44 }
45
46
47 /**
48 * 设置字符编码名称
49 *
50 * @param ba 传入的字节
51 * @param off 字节起始位置
52 * @param len 字节长度
53 * @return
54 */
55 static char[] decode(byte[] ba, int off, int len) {
56
57 //获取此字符集的规范名称,设置默认的字符编码名称
58 String csn = Charset.defaultCharset().name();
59
60 try {
61 // 使用提供缓存的字符集名称,就是csn
62 return decode(csn, ba, off, len);
63 } catch (UnsupportedEncodingException x) {
64 //抛出编码名称不对的异常
65 warnUnsupportedCharset(csn);
66 }
67 try {
68
69 // 使用ISO-8859-1作为编码名称
70 return decode("ISO-8859-1", ba, off, len);
71 } catch (UnsupportedEncodingException x) {
72
73 // 编译时抛出错误
74 MessageUtils.err("ISO-8859-1 charset not available: "
75 + x.toString());
76
77 // 退出编译
78 System.exit(1);
79
80 return null;
81 }
82 }
83
84
85 /**
86 * 字节数组转成字符串
87 *
88 * @param charsetName 编码名称
89 * @param ba 传入的字节
90 * @param off 字节起始位置
91 * @param len 字节长度
92 * @return
93 * @throws UnsupportedEncodingException
94 */
95 static char[] decode(String charsetName, byte[] ba, int off, int len)
96 throws UnsupportedEncodingException {
97
98 // 通过线程对字符串编码和解码
99 StringCoding.StringDecoder sd = deref(decoder);
100
101 // 判断字符编码名称是否为空,为空设置默认名称为ISO-8859-1,否则使用传入的值
102 String csn = (charsetName == null) ? "ISO-8859-1" : charsetName;
103
104 // 解出结果为空
105 if ((sd == null) ||
106 // 解出名称和传入的名称不等
107 !(csn.equals(sd.requestedCharsetName())
108 // 解出编码名称和传入的编码名称相等
109 || csn.equals(sd.charsetName()))) {
110
111 sd = null;
112
113 try {
114 //查找字符集
115 Charset cs = lookupCharset(csn);
116
117 // 字符集不为空
118 if (cs != null)
119
120 sd = new StringCoding.StringDecoder(cs, csn);
121 } catch (IllegalCharsetNameException x) {
122 }
123 if (sd == null)
124 throw new UnsupportedEncodingException(csn);
125 set(decoder, sd);
126 }
127 return sd.decode(ba, off, len);
128 }
129
130 /**
131 * 查找字符集
132 * @param csn
133 * @return
134 */
135 private static Charset lookupCharset(String csn) {
136 if (Charset.isSupported(csn)) {
137 try {
138 return Charset.forName(csn);
139 } catch (UnsupportedCharsetException x) {
140 throw new Error(x);
141 }
142 }
143 return null;
144 }
145
146 /**
147 * 通过构造函数将字符转化为字符串
148 * @param cs
149 * @param rcn
150 */
151 private StringDecoder(Charset cs, String rcn) {
152 this.requestedCharsetName = rcn;
153 this.cs = cs;
154 this.cd = cs.newDecoder()
155 .onMalformedInput(CodingErrorAction.REPLACE)
156 .onUnmappableCharacter(CodingErrorAction.REPLACE);
157 this.isTrusted = (cs.getClass().getClassLoader0() == null);
158 }源码分析:
1、是否数组越界
2、审核后进行字节数组转成字符串
应用:1 String sanwei="sanwich";
2
3 byte[] sanweiBytes = sanwei.getBytes();
4
5 System.out.println("字节:"+sanweiBytes);
6
7 String stringArrays = new String(sanweiBytes);
8
9 System.out.println("字节转换字符串:"+stringArrays);String(byte[],offset,count)
将字节数组中的一部分转成字符串
源码:1 /**
2 * 设置将几个字节转换为字符
3 *
4 * @param bytes 字节
5 * @param offset 起始位置
6 * @param length 转换几个字节为字符
7 */
8 public String(byte bytes[], int offset, int length) {
9
10 //审核是否越界
11 checkBounds(bytes, offset, length);
12 // 转换几个字节为字符
13 this.value = StringCoding.decode(bytes, offset, length);
14 }源码分析:
比上边多了设置字符串起始位置设置
应用:1 String sanwei="sanwich";
2
3 byte[] sanweiBytes = sanwei.getBytes();
4
5 System.out.println("字节:"+sanweiBytes);
6
7 String stringArrays = new String(sanweiBytes,0,5);
8
9 System.out.println("字节转换字符串:"+stringArrays); - 将字符串转成字节数组
byte[] getBytes()
源码:
1 /**
2 * 获取字节
3 *
4 * @return 返回字节数组
5 */
6 public byte[] getBytes() {
7 return StringCoding.encode(value, 0, value.length);
8 }
9
10 static byte[] encode(char[] ca, int off, int len) {
11 String csn = Charset.defaultCharset().name();
12 try {
13 // use charset name encode() variant which provides caching.
14 return encode(csn, ca, off, len);
15 } catch (UnsupportedEncodingException x) {
16 warnUnsupportedCharset(csn);
17 }
18 try {
19 return encode("ISO-8859-1", ca, off, len);
20 } catch (UnsupportedEncodingException x) {
21 // If this code is hit during VM initialization, MessageUtils is
22 // the only way we will be able to get any kind of error message.
23 MessageUtils.err("ISO-8859-1 charset not available: "
24 + x.toString());
25 // If we can not find ISO-8859-1 (a required encoding) then things
26 // are seriously wrong with the installation.
27 System.exit(1);
28 return null;
29 }
30 }源码分析:
1、是否数组越界
2、审核后进行字节数组转成字符串
应用:1 String sanwei = "sanwich";
2
3 byte[] sanweiBytes = sanwei.getBytes();
4
5 System.out.println("字符串转换字节:" + Arrays.toString(sanweiBytes)); - 将基本数据类型转成字符串
static String valueOf(int)
将整型转成字符串
源码:1 /**
2 * 数字转换字符串
3 *
4 * @param i 传入的数字
5 * @return 返回字符串
6 */
7 public static String valueOf(int i) {
8 return Integer.toString(i);
9 }
10
11 /**
12 * 数字转换字符串
13 *
14 * @param i 传入的数字
15 * @return 返回字符串
16 */
17 public static String toString(int i) {
18
19 //传入值是否等于最小边界值
20 if (i == Integer.MIN_VALUE)
21 return "-2147483648";
22
23 //传入值是否小于零,是的话返回1,否的话返回0
24 int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
25
26 //新建一个数组
27 char[] buf = new char[size];
28
29 //实际转化
30 getChars(i, size, buf);
31
32 //返回转化的结果
33 return new String(buf, true);
34 }
35
36
37 /**
38 * 获取字节数组
39 *
40 * 将传入的整数放入字符数组buf中,
41 * 字符从指定charPos处的最低有效数字开始(向后)开始向后放置在缓冲区中
42 *
43 *
44 * @param i 传入的数字
45 * @param index 传入素组大小
46 * @param buf 传入数组
47 */
48 static void getChars(int i, int index, char[] buf) {
49 int q, r;
50 int charPos = index;
51 char sign = 0;
52
53 if (i < 0) {
54 sign = '-';
55 i = -i;
56 }
57
58 // Generate two digits per iteration
59 while (i >= 65536) {
60 q = i / 100;
61 // really: r = i - (q * 100);
62 r = i - ((q << 6) + (q << 5) + (q << 2));
63 i = q;
64 buf[--charPos] = DigitOnes[r];
65 buf[--charPos] = DigitTens[r];
66 }
67
68 // Fall thru to fast mode for smaller numbers
69 // assert(i <= 65536, i);
70 for (; ; ) {
71 q = (i * 52429) >>> (16 + 3);
72 r = i - ((q << 3) + (q << 1)); // r = i-(q*10) ...
73 buf[--charPos] = digits[r];
74 i = q;
75 if (i == 0) break;
76 }
77 if (sign != 0) {
78 buf[--charPos] = sign;
79 }
80 }源码分析:
1、将传入的整数放入字符数组buf中
2、字符从指定charPos处的最低有效数字开始(向后)开始向后放置在缓冲区中
应用:1 int number = 666;
2
3 String s = "";
4 s = s.valueOf(number);
5
6 System.out.println("数字转换字符串:" + s);static String valueOf(double)
将双精度浮点型转成字符串
源码:1 /**
2 * 将double转化为string
3 *
4 * @param d 传入的double
5 * @return 返回字符串
6 */
7 public static String valueOf(double d) {
8 return Double.toString(d);
9 }
10
11
12 public static String toString(double d) {
13 return FloatingDecimal.toJavaFormatString(d);
14 }
15
16 public static String toJavaFormatString(double var0) {
17 return getBinaryToASCIIConverter(var0).toJavaFormatString();
18 }
19
20 public static FloatingDecimal.BinaryToASCIIConverter getBinaryToASCIIConverter(double var0) {
21 return getBinaryToASCIIConverter(var0, true);
22 }
23
24 static FloatingDecimal.BinaryToASCIIConverter getBinaryToASCIIConverter(double var0, boolean var2) {
25 long var3 = Double.doubleToRawLongBits(var0);
26 boolean var5 = (var3 & -9223372036854775808L) != 0L;
27 long var6 = var3 & 4503599627370495L;
28 int var8 = (int)((var3 & 9218868437227405312L) >> 52);
29 if (var8 == 2047) {
30 if (var6 == 0L) {
31 return var5 ? B2AC_NEGATIVE_INFINITY : B2AC_POSITIVE_INFINITY;
32 } else {
33 return B2AC_NOT_A_NUMBER;
34 }
35 } else {
36 int var9;
37 if (var8 == 0) {
38 if (var6 == 0L) {
39 return var5 ? B2AC_NEGATIVE_ZERO : B2AC_POSITIVE_ZERO;
40 }
41
42 int var10 = Long.numberOfLeadingZeros(var6);
43 int var11 = var10 - 11;
44 var6 <<= var11;
45 var8 = 1 - var11;
46 var9 = 64 - var10;
47 } else {
48 var6 |= 4503599627370496L;
49 var9 = 53;
50 }
51
52 var8 -= 1023;
53 FloatingDecimal.BinaryToASCIIBuffer var12 = getBinaryToASCIIBuffer();
54 var12.setSign(var5);
55 var12.dtoa(var8, var6, var9, var2);
56 return var12;
57 }
58 }源码分析:
用封装类型转化
应用:1 double number = 666.00;
2
3 String s = "";
4 s = s.valueOf(number);
5
6 System.out.println("数字转换字符串:" + s);
4、替换
- 字符串替换,将oldchar替换为newchar
String replace(oldchar,newchar)
源码:1 /**
2 * 替换字符串
3 *
4 * @param target 原始字符串
5 * @param replacement 替换字符串
6 * @return 新的字符串
7 */
8 public String replace(CharSequence target, CharSequence replacement) {
9 return Pattern.compile(target.toString(), Pattern.LITERAL).matcher(
10 this).replaceAll(Matcher.quoteReplacement(replacement.toString()));
11 }
12
13
14 public static Pattern compile(String regex, int flags) {
15 return new Pattern(regex, flags);
16 }
17
18
19 private Pattern(String p, int f) {
20 pattern = p;
21 flags = f;
22
23 // to use UNICODE_CASE if UNICODE_CHARACTER_CLASS present
24 if ((flags & UNICODE_CHARACTER_CLASS) != 0)
25 flags |= UNICODE_CASE;
26
27 // Reset group index count
28 capturingGroupCount = 1;
29 localCount = 0;
30
31 if (pattern.length() > 0) {
32 compile();
33 } else {
34 root = new Start(lastAccept);
35 matchRoot = lastAccept;
36 }
37 }源码分析:
1、通过正则表达式替换字符串或字符
2、将结果放入一个新的String对象中返回
应用:1 String oldchar = "san";
2 String newchar = "two";
3
4 System.out.println("原始字符串:" + oldchar);
5 oldchar=oldchar.replace(oldchar,newchar);
6 System.out.println("替换后符串:" + oldchar);
5、切割
- 通过指定分隔符对字符串进行切片
String[] split(regex)
源码:1 public String[] split(String regex) {
2 return split(regex, 0);
3 }
4
5 public String[] split(String regex, int limit) {
6 /* fastpath if the regex is a
7 (1)one-char String and this character is not one of the
8 RegEx's meta characters ".$|()[{^?*+\\", or
9 (2)two-char String and the first char is the backslash and
10 the second is not the ascii digit or ascii letter.
11 */
12 char ch = 0;
13 if (((regex.value.length == 1 &&
14 ".$|()[{^?*+\\".indexOf(ch = regex.charAt(0)) == -1) ||
15 (regex.length() == 2 &&
16 regex.charAt(0) == '\\' &&
17 (((ch = regex.charAt(1))-'0')|('9'-ch)) < 0 &&
18 ((ch-'a')|('z'-ch)) < 0 &&
19 ((ch-'A')|('Z'-ch)) < 0)) &&
20 (ch < Character.MIN_HIGH_SURROGATE ||
21 ch > Character.MAX_LOW_SURROGATE))
22 {
23 int off = 0;
24 int next = 0;
25 boolean limited = limit > 0;
26 ArrayList<String> list = new ArrayList<>();
27 while ((next = indexOf(ch, off)) != -1) {
28 if (!limited || list.size() < limit - 1) {
29 list.add(substring(off, next));
30 off = next + 1;
31 } else { // last one
32 //assert (list.size() == limit - 1);
33 list.add(substring(off, value.length));
34 off = value.length;
35 break;
36 }
37 }
38 // If no match was found, return this
39 if (off == 0)
40 return new String[]{this};
41
42 // Add remaining segment
43 if (!limited || list.size() < limit)
44 list.add(substring(off, value.length));
45
46 // Construct result
47 int resultSize = list.size();
48 if (limit == 0) {
49 while (resultSize > 0 && list.get(resultSize - 1).length() == 0) {
50 resultSize--;
51 }
52 }
53 String[] result = new String[resultSize];
54 return list.subList(0, resultSize).toArray(result);
55 }
56 return Pattern.compile(regex).split(this, limit);
57 }源码分析:
1、字符进行转化为字节
2、进行遍历匹配
3、排除匹配的字符,输出新的结果
应用:1 String stringSpilt = "san,lllll";
2
3 String[] split = stringSpilt.split(",");
4
5 for (int i = 0; i < split.length; i++) {
6 System.out.println("切割后第"+(i+1)+"字符串是:"+split[i]);
7 }
6、子串
- 获取字符串中的一部分
String substring(begin)
根据起始位置,获取其之后的字符串
源码:1 /**
2 * 输出beginIndex以后的字串
3 *
4 * @param beginIndex 传入的角标值
5 * @return 新的字符串
6 */
7 public String substring(int beginIndex) {
8
9 // 是否小于零越界
10 if (beginIndex < 0) {
11 throw new StringIndexOutOfBoundsException(beginIndex);
12 }
13
14 // 数组与传入的角标差值
15 int subLen = value.length - beginIndex;
16
17 // 是否小于零越界
18 if (subLen < 0) {
19 throw new StringIndexOutOfBoundsException(subLen);
20 }
21
22 // 传入值是否等于零,等于零返回元素组,不等于零创建新的数组,执行构造函数,拷贝数组需要部分,输出新数组
23 return (beginIndex == 0) ? this : new String(value, beginIndex, subLen);
24 }源码分析:
传入值是否等于零,等于零返回元素组,不等于零创建新的数组,执行构造函数,拷贝数组需要部分,输出新数组
应用:1 String stringSpilt = "san,lllll";
2
3 String substringValue = stringSpilt.substring(5);
4
5 System.out.println("输出5以后的字串:"+substringValue);String substring(begin,end)
根据起始位置和结束为止,获取起始和结束中间的字符串
源码:1 public String substring(int beginIndex, int endIndex) {
2 if (beginIndex < 0) {
3 throw new StringIndexOutOfBoundsException(beginIndex);
4 }
5 if (endIndex > value.length) {
6 throw new StringIndexOutOfBoundsException(endIndex);
7 }
8 int subLen = endIndex - beginIndex;
9 if (subLen < 0) {
10 throw new StringIndexOutOfBoundsException(subLen);
11 }
12 return ((beginIndex == 0) && (endIndex == value.length)) ? this
13 : new String(value, beginIndex, subLen);
14 }源码分析:
传入值是否等于零,等于零返回元素组,不等于零创建新的数组,执行构造函数,拷贝数组需要部分,输出新数组(多了一个end判断而已,其他同上)
应用:1 String stringSpilt = "san,lllll";
2
3 String substringValue = stringSpilt.substring(3,6);
4
5 System.out.println("输出3到6之间的字串:" + substringValue);
7、转换、去除空格、比较
- 1、 将字符串转成大写或则小写
String toUpperCase()
字符串转换为大写字母
源码:1 /**
2 * 字符串转换为大写
3 *
4 * @return 转化为大写的字符串
5 */
6 public String toUpperCase() {
7 return toUpperCase(Locale.getDefault());
8 }
9
10 /**
11 * 字符串转换为大写
12 *
13 * @param locale 用于识别语言的标签
14 * @return 新的字符串
15 */
16 public String toUpperCase(Locale locale) {
17
18 // 用于识别语言的标签为空,破案出空指针异常
19 if (locale == null) {
20 throw new NullPointerException();
21 }
22
23 int firstLower;
24
25 //获取数组长度
26 final int len = value.length;
27
28 /* Now check if there are any characters that need to be changed. */
29 scan:
30 {
31 for (firstLower = 0; firstLower < len; ) {
32 int c = (int) value[firstLower];
33 int srcCount;
34 if ((c >= Character.MIN_HIGH_SURROGATE)
35 && (c <= Character.MAX_HIGH_SURROGATE)) {
36 c = codePointAt(firstLower);
37 srcCount = Character.charCount(c);
38 } else {
39 srcCount = 1;
40 }
41 int upperCaseChar = Character.toUpperCaseEx(c);
42 if ((upperCaseChar == Character.ERROR)
43 || (c != upperCaseChar)) {
44 break scan;
45 }
46 firstLower += srcCount;
47 }
48 return this;
49 }
50
51 /* result may grow, so i+resultOffset is the write location in result */
52 int resultOffset = 0;
53 char[] result = new char[len]; /* may grow */
54
55 /* Just copy the first few upperCase characters. */
56 System.arraycopy(value, 0, result, 0, firstLower);
57
58 String lang = locale.getLanguage();
59 boolean localeDependent =
60 (lang == "tr" || lang == "az" || lang == "lt");
61 char[] upperCharArray;
62 int upperChar;
63 int srcChar;
64 int srcCount;
65 for (int i = firstLower; i < len; i += srcCount) {
66 srcChar = (int) value[i];
67 if ((char) srcChar >= Character.MIN_HIGH_SURROGATE &&
68 (char) srcChar <= Character.MAX_HIGH_SURROGATE) {
69 srcChar = codePointAt(i);
70 srcCount = Character.charCount(srcChar);
71 } else {
72 srcCount = 1;
73 }
74 if (localeDependent) {
75 upperChar = ConditionalSpecialCasing.toUpperCaseEx(this, i, locale);
76 } else {
77 upperChar = Character.toUpperCaseEx(srcChar);
78 }
79 if ((upperChar == Character.ERROR)
80 || (upperChar >= Character.MIN_SUPPLEMENTARY_CODE_POINT)) {
81 if (upperChar == Character.ERROR) {
82 if (localeDependent) {
83 upperCharArray =
84 ConditionalSpecialCasing.toUpperCaseCharArray(this, i, locale);
85 } else {
86 upperCharArray = Character.toUpperCaseCharArray(srcChar);
87 }
88 } else if (srcCount == 2) {
89 resultOffset += Character.toChars(upperChar, result, i + resultOffset) - srcCount;
90 continue;
91 } else {
92 upperCharArray = Character.toChars(upperChar);
93 }
94
95 /* Grow result if needed */
96 int mapLen = upperCharArray.length;
97 if (mapLen > srcCount) {
98 char[] result2 = new char[result.length + mapLen - srcCount];
99 System.arraycopy(result, 0, result2, 0, i + resultOffset);
100 result = result2;
101 }
102 for (int x = 0; x < mapLen; ++x) {
103 result[i + resultOffset + x] = upperCharArray[x];
104 }
105 resultOffset += (mapLen - srcCount);
106 } else {
107 result[i + resultOffset] = (char) upperChar;
108 }
109 }
110 return new String(result, 0, len + resultOffset);
111 }源码分析:
字符串转化为答谢字母
应用:1 String stringSpilt = "sanlllll";
2
3 String substringValue = stringSpilt.toUpperCase();
4
5 System.out.println("将字符串全部转换为大写字母:" + substringValue);String toLowerCase()
字符串转换为小写字母
源码:1 /**
2 * 字符串转化为小写字母
3 *
4 * @return
5 */
6 public String toLowerCase() {
7 return toLowerCase(Locale.getDefault());
8 }
9
10 public String toLowerCase(Locale locale) {
11 if (locale == null) {
12 throw new NullPointerException();
13 }
14
15 int firstUpper;
16 final int len = value.length;
17
18 /* Now check if there are any characters that need to be changed. */
19 scan: {
20 for (firstUpper = 0 ; firstUpper < len; ) {
21 char c = value[firstUpper];
22 if ((c >= Character.MIN_HIGH_SURROGATE)
23 && (c <= Character.MAX_HIGH_SURROGATE)) {
24 int supplChar = codePointAt(firstUpper);
25 if (supplChar != Character.toLowerCase(supplChar)) {
26 break scan;
27 }
28 firstUpper += Character.charCount(supplChar);
29 } else {
30 if (c != Character.toLowerCase(c)) {
31 break scan;
32 }
33 firstUpper++;
34 }
35 }
36 return this;
37 }
38
39 char[] result = new char[len];
40 int resultOffset = 0; /* result may grow, so i+resultOffset
41 * is the write location in result */
42
43 /* Just copy the first few lowerCase characters. */
44 System.arraycopy(value, 0, result, 0, firstUpper);
45
46 String lang = locale.getLanguage();
47 boolean localeDependent =
48 (lang == "tr" || lang == "az" || lang == "lt");
49 char[] lowerCharArray;
50 int lowerChar;
51 int srcChar;
52 int srcCount;
53 for (int i = firstUpper; i < len; i += srcCount) {
54 srcChar = (int)value[i];
55 if ((char)srcChar >= Character.MIN_HIGH_SURROGATE
56 && (char)srcChar <= Character.MAX_HIGH_SURROGATE) {
57 srcChar = codePointAt(i);
58 srcCount = Character.charCount(srcChar);
59 } else {
60 srcCount = 1;
61 }
62 if (localeDependent ||
63 srcChar == '\u03A3' || // GREEK CAPITAL LETTER SIGMA
64 srcChar == '\u0130') { // LATIN CAPITAL LETTER I WITH DOT ABOVE
65 lowerChar = ConditionalSpecialCasing.toLowerCaseEx(this, i, locale);
66 } else {
67 lowerChar = Character.toLowerCase(srcChar);
68 }
69 if ((lowerChar == Character.ERROR)
70 || (lowerChar >= Character.MIN_SUPPLEMENTARY_CODE_POINT)) {
71 if (lowerChar == Character.ERROR) {
72 lowerCharArray =
73 ConditionalSpecialCasing.toLowerCaseCharArray(this, i, locale);
74 } else if (srcCount == 2) {
75 resultOffset += Character.toChars(lowerChar, result, i + resultOffset) - srcCount;
76 continue;
77 } else {
78 lowerCharArray = Character.toChars(lowerChar);
79 }
80
81 /* Grow result if needed */
82 int mapLen = lowerCharArray.length;
83 if (mapLen > srcCount) {
84 char[] result2 = new char[result.length + mapLen - srcCount];
85 System.arraycopy(result, 0, result2, 0, i + resultOffset);
86 result = result2;
87 }
88 for (int x = 0; x < mapLen; ++x) {
89 result[i + resultOffset + x] = lowerCharArray[x];
90 }
91 resultOffset += (mapLen - srcCount);
92 } else {
93 result[i + resultOffset] = (char)lowerChar;
94 }
95 }
96 return new String(result, 0, len + resultOffset);
97 }源码分析:
同上
应用:1 String stringSpilt = "ASllll";
2
3 String substringValue = stringSpilt.toLowerCase();
4
5 System.out.println("将字符串全部转换为小写字母:" + substringValue); - 2、 将字符串两端的多个空格去除
String trim()
源码:
1 /**
2 * 去除首首尾空格
3 *
4 * @return 获取新数组
5 */
6 public String trim() {
7 // 数组长度
8 int len = value.length;
9
10 int st = 0;
11
12 //建立新的数组
13 char[] val = value;
14
15 //减去开头的空格
16 while ((st < len) && (val[st] <= ' ')) {
17 st++;
18 }
19
20 // 减去末尾的空格
21 while ((st < len) && (val[len - 1] <= ' ')) {
22 len--;
23 }
24
25 // 得到新的数组放入新的字符串中
26 return ((st > 0) || (len < value.length)) ? substring(st, len) : this;
27 }源码分析:
1、建立新的数组
2、减去开头的空格或减去末尾的空格
3、得到新的数组放入新的字符串中
应用:1 String stringSpilt = " ASl lll ";
2
3 String substringValue = stringSpilt.trim();
4
5 System.out.println("将字符串空格去除:" + substringValue); - 3、 对两个字符串进行自然顺序的比较
int compareTo(string)
源码:
1 /**
2 * 两个字符串比较
3 *
4 * @param anotherString 另一个字符串
5 * @return
6 */
7 public int compareTo(String anotherString) {
8
9 // 原字符串长度
10 int len1 = value.length;
11
12 // 另一个字符串长度
13 int len2 = anotherString.value.length;
14
15 //两个字符串中长度较小的值
16 int lim = Math.min(len1, len2);
17
18 // 原字符串放入新数组
19 char v1[] = value;
20
21 // 另一个字符串放入新的数组
22 char v2[] = anotherString.value;
23
24 int k = 0;
25
26 // 两个字符串中长度较小的值大于零
27 while (k < lim) {
28
29 // 取出原字符串中的一个字符
30 char c1 = v1[k];
31
32 // 取出另一个字符串中的一个字符
33 char c2 = v2[k];
34
35 // 两个字符不想等
36 if (c1 != c2) {
37
38 // 返回字符相减的值
39 return c1 - c2;
40 }
41
42 k++;
43 }
44
45 // 字符长度相减的值
46 return len1 - len2;
47 }源码分析:
两个字符串遍历比较是否相同,返回参与比较的前后两个字符串的asc码的差值
应用:1 String stringSpilt = "abc";
2
3 int compareToResult = stringSpilt.compareTo("abc");
4
5 System.out.println("将两个字符串进行比较:" + compareToResult);
JDK源码阅读-------自学笔记(三)(java.lang.String String用法和描述浅析)的更多相关文章
- JDK源码阅读-------自学笔记(一)(java.lang.Object重写toString源码)
一.前景提要 Object类中定义有public String toString()方法,其返回值是 String 类型. 二.默认返回组成 类名+@+16进制的hashcode,当使用打印方法打印的 ...
- JDK源码阅读-------自学笔记(二十四)(java.util.LinkedList 再探 自定义讲解)
一.实现get方法 1.一般思维实现思路 1).将对象的值放入一个中间变量中. 2).遍历索引值,将中间量的下一个元素赋值给中间量. 3).返回中间量中的元素值. 4).示意图 get(2),传入角标 ...
- JDK源码阅读-------自学笔记(二十五)(java.util.Vector 自定义讲解)
Vector 向量 Vector简述 1).Vector底层是用数组实现的List 2).虽然线程安全,但是效率低,所以并不是安全就是好的 3).底层大量方法添加synchronized同步标记,sy ...
- JDK源码阅读-------自学笔记(五)(浅析数组)
一.数组基础 1.定义和特点 数组也可以看做是对象,数组变量属于引用类型,数组中每个元素相当于该队形的成员变量,数组对象存储在堆中. 2.初始化数组 常用类初始化 // 整型初始化 int[] int ...
- JDK源码阅读-DirectByteBuffer
本文转载自JDK源码阅读-DirectByteBuffer 导语 在文章JDK源码阅读-ByteBuffer中,我们学习了ByteBuffer的设计.但是他是一个抽象类,真正的实现分为两类:HeapB ...
- JDK源码阅读(三):ArraryList源码解析
今天来看一下ArrayList的源码 目录 介绍 继承结构 属性 构造方法 add方法 remove方法 修改方法 获取元素 size()方法 isEmpty方法 clear方法 循环数组 1.介绍 ...
- JDK源码阅读(一):Object源码分析
最近经过某大佬的建议准备阅读一下JDK的源码来提升一下自己 所以开始写JDK源码分析的文章 阅读JDK版本为1.8 目录 Object结构图 构造器 equals 方法 getClass 方法 has ...
- JDK源码阅读-FileOutputStream
本文转载自JDK源码阅读-FileOutputStream 导语 FileOutputStream用户打开文件并获取输出流. 打开文件 public FileOutputStream(File fil ...
- JDK源码阅读-FileInputStream
本文转载自JDK源码阅读-FileInputStream 导语 FileIntputStream用于打开一个文件并获取输入流. 打开文件 我们来看看FileIntputStream打开文件时,做了什么 ...
- JDK源码阅读-RandomAccessFile
本文转载自JDK源码阅读-RandomAccessFile 导语 FileInputStream只能用于读取文件,FileOutputStream只能用于写入文件,而对于同时读取文件,并且需要随意移动 ...
随机推荐
- #排列组合,dp#LOJ 6069 「2017 山东一轮集训 Day4」塔
题目传送门 分析 两点之间的最小距离其实是由两点高度最大值决定的, 求出长度为 \(n\) 的排列所需距离的方案数,剩下还能放的距离可以用插板法放进去. 也就是 \(\sum_{i=1}^{n^2}f ...
- #dp,排列#LOJ 2743「JOI Open 2016」摩天大楼
题目 将互不相同的 \(n\) 个数重排,使得相邻两数差的总和不超过 \(L\) 的有多少种方式. \(n\leq 100,L\leq 1000\) 分析 对于排列的问题,有一种很妙的方法就是从小到大 ...
- #主席树,离散,扫描线#洛谷 3168 [CQOI2015]任务查询系统
题目 分析 询问显然得预处理,考虑以优先级建权值线段树, 将优先级离散化处理,那么第\(k\)大可以用线段树来求 那任务怎么办,考虑时间用扫描线的方法,按照时间建新的线段树 把任务分成两部分,在两端差 ...
- 使用OHOS SDK构建assimp
参照OHOS IDE和SDK的安装方法配置好开发环境. 从github下载源码. 执行如下命令: git clone https://github.com/assimp/assimp.git 进入源码 ...
- 记录C++,base64解码写PDF文件遇到的坑
不得不bb一下, 场景:用户传base64数据,我生成PDF文件保存到指定路径下 背景:在前人写好的工程上增加这个功能,工程中有base64的.h, .cpp 文件,我试了base64编码没有问题,所 ...
- 什么是慢SQL且如何查看慢SQL
什么是慢 SQL 且如何查看慢 SQL? 介绍 某个 SQL 执行时间超过指定时间时称为慢 SQL.我们可以查看慢 SQL,包括历史慢 SQL 以及当前慢 SQL. 查看历史慢 SQL 首先要设置 l ...
- c# 多线程传值注意的地方
前言 下面介绍多线程传值的几种方式,并说明注意点. 正文 static void Main(string[] args) { SampleTread thead = new SampleTread(1 ...
- 第四章:if else switch使用
/* * @Issue: 输入整数a和b,若a²+b²大于100,则输出a²+b²之和的百位以上的数字,否则直接输出a²+b²的和 * @Author: 一届书生 * @LastEditTime : ...
- keycloak~jwt的rs256签名的验证方式
接口地址 keycloak开放接口地址:/auth/realms/fabao/.well-known/openid-configuration rsa算法相关术语 RSA算法是一种非对称加密算法,其安 ...
- Windows 系统上如何安装 Python 环境(详细教程)
Windows 系统上如何安装 Python 环境(详细教程) 目前,Python有两个版本,一个是2.x版,一个是3.x版,这两个版本是不兼容的.由于2.x版官方只维护到2020年,所以以3.x版作 ...