概述
String 相对于StringBuffer 和 StringBuilder。 String 的特点是不可变。一旦创建就不可变。
继承关系
实现了3个接口 implements java.io.Serializable,Comparable, CharSequence
重要成员属性
private final char value[];
String的底层是采用char[]来存储数据的。若给String类型的对象重新赋值,其实是指引用了一个 重新创建的char[]。String类型的不可变,其实是指引用char[]本身没有改变,只是String的引用发生了变化。
构造器
生成一个新的String对象。
public String() {
this.value = "".value;
}
还有其他若干重载的构造器:
public String(java.lang.String)
public String(char[])
public String(char[], int, int)
public String(int[], int, int)
public String(byte[], int, int, int)
public String(byte[], int)
public String(byte[], int, int, java.lang.String)
public String(byte[], int, int, Charset)
public String(byte[], java.lang.String)
public String(byte[], Charset)
public String(byte[], int, int)
public String(byte[])
public String(StringBuffer)
public String(StringBuilder)
关键方法
+ length()
返回字符串长度
public int length() {
return value.length;
}
+ isEmpty()
判断是否为空,当且仅当String对象的长度为0时,返回true
public boolean isEmpty() {
return value.length == 0;
}
+ charAt(int index)
返回指定序号处的字符
public char charAt(int index) {
if ((index < 0) || (index >= value.length)) {
throw new StringIndexOutOfBoundsException(index);
}
return value[index];
}
+ getBytes()
使用平台默认的字符集,将String对象转化为byte序列存储到一个新的数组中。
public byte[] getBytes() {
return StringCoding.encode(value, 0, value.length);
}
+ equals()
当切仅当另一个对象也是String,并且两个String包含的字符序列相同时,返回true。
public boolean equals(Object anObject) { ... }
此外还有public boolean equalsIgnoreCase()方法,忽略大小写进行比较。
+ contentEquals()
和一个对象比较,如果字符序列相同,那么返回true。 如果
public boolean contentEquals(StringBuffer sb) {
return contentEquals((CharSequence)sb);
}
public boolean contentEquals(CharSequence cs) {
...
}
+ compareTo(String anotherString)
怎么比较呢。举个例子;
- String str1 = "abc"; String str2 = "abcd"; 从前到后开始比较,发现两个字符串公共部分完全一致,但是另一个字符串长度大一些,那么返回 str1.Length - str2.length
- String a = "123" String b = "134" 那么在index=1处,两个字符不一样,返回在字典中的位置差,即 "2" - "3",返回值 -1。
public int compareTo(String anotherString) { ... }
+ startsWith()
判断字符串是否以目标字符串开头。
public boolean startsWith(String prefix) { ... }
public boolean startsWith(String prefix, int toffset) { ... }
+ endsWith()
判断字符串是否以目标字符串结束。
public boolean endsWith(String suffix) { ... }
+ indexOf()
计算目标字符串第一次出现的位置的索引值。
public int indexOf(int ch, int fromIndex) { ... }
+ lastIndexOf()
判断目标字符串最后一次出现的位置的索引值。
public int lastIndexOf(int ch) { ... }
+ substring(int beginIndex)
根据开始索引,获取字符串的子串。
public String substring(int beginIndex) { ... }
+ concat()
把目标String添加到当前String末尾
public String concat(String str) { ... }
+ replace(char oldChar, char newChar)
把当前String中的oldChar替换为newChar。
public String replace(char oldChar, char newChar) { ... }
+ matches(String regex)
判断当前字符串是否符合目标正则
public boolean matches(String regex) {
return Pattern.matches(regex, this);
}
+ contains(CharSequence s)
判断当前String是否包含目标字符串序列。
public boolean contains(CharSequence s) {
return indexOf(s.toString()) > -1;
}
+ split(String regex)
以目标字符串作为分割符,将当前字符串分割为若干字符串,以String数组形式返回。
public String[] split(String regex) { ... }
public String[] split(String regex, int limit) { ... }
+ join(CharSequence delimiter, CharSequence... elements)
用指定的分隔符,将目标字符串数组拼接起来,返回String。
public static String join(CharSequence delimiter, CharSequence... elements) { ... }
public static String join(CharSequence delimiter,
Iterable<? extends CharSequence> elements) { ... }
+ toLowerCase(Locale locale)
转化为小写
public String toLowerCase(Locale locale) { ... }
+ toUpperCase(Locale locale)
转化为大写
public String toUpperCase(Locale locale) { ... }
public String toUpperCase() { ... }
trim()
去掉先后空格
public String trim() { ... }
valueOf()
返回代表目标对象的字符串实现的。各种
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
实现原理
String类的底层是采用字符数组实现的。各种操作其实都是基于字符数组的操作。
常见问题
问题一
以下代码的执行结果是?
String b = "abc";
String c = "abc";
System.out.println(b.equals(c));
>> true
因为字符串"abc"出现过,所以之后定义String的时候,其实是直接引用到第一次创建的"abc"。所以两个对象是相同的。
结语
需要区分String,StringBuffer,StringBuilder的特点和使用场景。 String常常用于存储是不可变的字符串序列。如果一个字符串需要频繁变更,那么最好是使用StringBuffer或者StringBuilder来存储。 StringBuffer和StringBuilder之间的区别在于: StringBuffer 是线程安全的。但是速度会相对慢。 StringBuilder 不是线程安全的,访问速度高。 所以在单线程中使用频繁变更的字符串,应该使用StringBuilder来存储。 在多线程中存储频繁变更的字符串,应该使用StringBuffer来存储。
希望和大家多多交流
我16年毕业以后,做的是前端,目前打算深入学习java开发。内容有任何问题,欢迎各位小伙伴们指正,也希望小伙伴们给我点赞和关注,给我留言,一起交流讨论,共同进步。