接下来我们进行Sting的学习,这个类算是很常用的。
String继承了三个接口:1
public final class String implements java.io.Serializable, Comparable<String>, CharSequence{}
Serializable接口只是做一个标识,Comparable接口是赋予了String比较的能力,CharSequence接口则是对String内部的Char[]操作提供方便的参数。
1 | /** The value is used for character storage. */ |
从这里可以看出String内部其实是char数组。
String有大量的构造方法,都是调用了其他工具类中的方法,比如Arrays.copyOf()、Arrays.copyOfRange()等等。
本来想一一介绍,但是看了一圈觉得并没有这个必要,我就挑几个比较特别的说说吧。1
2
3
4
5
6
7
8
9
10public static String join(CharSequence delimiter, CharSequence... elements) {
Objects.requireNonNull(delimiter);
Objects.requireNonNull(elements);
// Number of elements not likely worth Arrays.stream overhead.
StringJoiner joiner = new StringJoiner(delimiter);
for (CharSequence cs: elements) {
joiner.add(cs);
}
return joiner.toString();
}
join()方法是在JDK1.8之后新加的,他的作用如下:1
System.out.println(String.join(",","123","123"));//print: 123,123
这个函数可以方便我们进行数据展示的时候免于出现一连串的“”+””+…+””的蹩脚操作,也避免了删除最后一个字符的操作,他的内部实现其实是StringBuilder,即能够线程安全的展示数据。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33public 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) {//循环比较value
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
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;
}
equals本身没什么好说的,但是这个hashCode有点厉害,这个散列值为什么要这么计算请自行百度。
1 | //这里只说int型参,这个int是Unicode code,不是位置。 |
例如:1
2String str = "abc";
System.out.println(str.indexOf(98));// 1
indexOf(String str)用来返回字符所在位置的下标。1
2
3public String substring(int beginIndex);
public String substring(int beginIndex, int endIndex);
public CharSequence subSequence(int beginIndex, int endIndex);
substring方法用来分割字符串,最终实现都是重新new一个String:1
new String(value, beginIndex, subLen)
equalsIgnoreCase也比较有用,用于不区分大小写比较的情况1
2
3
4
5
6public boolean equalsIgnoreCase(String anotherString) {
return (this == anotherString) ? true
: (anotherString != null)
&& (anotherString.value.length == value.length)
&& regionMatches(true, 0, anotherString, 0, value.length);
}
format是非常有用的一个方法,尤其你自己封装持久层时,简直是神器!支持的转换符有:
| 转换符 | 描述 | 转换符 | 描述 |
|---|---|---|---|
| %s | 字符串类型 | %c | 字符类型 |
| %b | 布尔类型 | %d | 十进制整数类型 |
| %x | 十六进制整数类型 | %o | 八进制整数类型 |
| %f | 浮点类型 | %a | 十六进制浮点类型 |
| %e | 指数类型 | %g | 通用浮点类型 |
| %h | 散列码类型 | %% | 百分比类型 |
| %n | 换行符 | %tx | 时间日期类型 |
1 | public static String format(String format, Object... args) { |
intern方法用来将String对象加入常量池并返回引用,在循环、递归有限集合中灰常有用!1
public native String intern();