Java String(字符串)
- 声明与初始化
- String str = "i" 与 String str = new String("i") 一样吗?
- String、StringBuffer与StringBuilder的区别
- 字符串方法
- charAt,length,concat,trim,isEmpty
- substring
- split
- replace,replaceAll,replaceFirst
- indexOf,lastIndexOf,compareTo
- getBytes
- equals,equalsIgnoreCase
- matches
- toLowerCase,toUpperCase
- startsWith,endsWith,contains
声明与初始化
// 无参构造方法,用来创建空字符串的String对象
String str1 = new String();
// 有参构造方法
String str2 = new String("123");
String str3 = new String(str2);
// 用字符数组obj创建一个String对象
// 本质上是由 字符数组 组成的
char[] obj = {'a','b','c'};
String str4 = new String(obj);
// 空字符串,长度为0
String str5 = "";
String str6 = "abc";
// 这样写无法直接使用str,编译器提示Initialize variable(初始化变量)
String str;
String str = “i” 与 String str = new String(“i”) 一样吗?
不一样,因为内存的分配方式不一样。String str = "i"的方式,Java 虚拟机会将其分配到常量池中;而 String str = new String(“i”) 则会被分到堆内存中。
String str1 = "test";
String str2 = "test";
// str1与str2都指向常量池中"test"
System.out.println(str1 == str2); // true
String str3 = new String("test");
String str4 = new String("test");
// str3和str4指向的不是同一个地址,堆中不同的地址指向相同的常量池里的数据
System.out.println(str3 == str4); // false
String str5 = "test";
String str6 = new String("test");
// str5指向常量池里的"test"
// str6指向堆中的地址,堆地址指向常量池里的"test"
System.out.println(str5 == str6); // false
char[] array = { 't', 'e', 's', 't' };
String str7 = "test";
String str8 = new String(array);
System.out.println(str7 == str8); // false
处理编码格式:
// 构造方法-编码格式
public String(byte bytes[], String charsetName) throws UnsupportedEncodingException
public String(byte bytes[], Charset charset)
public String(byte bytes[])
// 在捕获或抛出异常后使用
// byte[] result
String msg = new String(result, "UTF-8");
String、StringBuffer与StringBuilder的区别
String:适用于少量的字符串操作
的情况。
StringBuilder:适用于单线程下
,在字符缓冲区进行大量操作的情况,是线程不安全的
。
StringBuffer:适用于多线程下
,在字符缓冲区进行大量操作的情况,是线程安全的
。
String 声明的是不可变的对象,每次操作都会生成新的 String 对象,然后将指针指向新的 String 对象,而 StringBuffer、StringBuilder 可以在原有对象的基础上进行操作,所以在经常改变字符串内容的情况下最好不要使用 String。
运行速度快慢为:StringBuilder > StringBuffer > String
String最慢的原因:
String为字符串常量,而StringBuilder和StringBuffer均为字符串变量,即String对象一旦创建之后该对象是不可更改的,但后两者的对象是变量,是可以更改的。
线程安全:
如果一个StringBuffer对象在字符串缓冲区被多个线程使用时,StringBuffer中很多方法可以带有synchronized关键字,所以可以保证线程是安全的。
但StringBuilder的方法则没有该关键字,所以不能保证线程安全,有可能会出现一些错误的操作。所以如果要进行的操作是多线程的,那么就要使用StringBuffer,但是在单线程的情况下,还是建议使用速度比较快的StringBuilder。
几个关键的方法:
StringBuilder builder = new StringBuilder();
// append方法用于添加信息
builder.append("123");
// 转化为String
builder.toString();
// 字符串反转
builder.reverse();
StringBuffer buffer = new StringBuffer();
// append方法用于添加信息
buffer.append("123");
// 转化为String
buffer.toString();
// 字符串反转
buffer.reverse();
字符串方法
charAt,length,concat,trim,isEmpty
public char charAt(int index)
:返回该字符串指定位的字符,从0开始,小于0或超过最大长度则抛出越界错误。
public int length()
:返回该字符串的长度。
public String concat(String str)
:字符串连接,相当于 + 。
public String trim()
:消除字符串两端的空格,但对于中间的空格不处理。
public boolean isEmpty()
:字符串长度为0,返回true。
String str = "123abc";
System.out.println(str.charAt(0)); // 1
System.out.println(str.charAt(3)); // a
System.out.println(str.length()); // 6
String str1 = " a b c ";
System.out.println(str1.trim()); //a b c
从Java 11开始,String 类包含3个其它方法,这些方法有助于消除多余空格。使用 Character.isWhitespace(char) 方法来确定空白字符。
public String strip()
:消除字符串两端的空格,对于中间的空格不处理。
public String stripLeading()
:消除左侧的空格,对于中间和右侧的空格不处理。
public String stripTrailing()
:消除右侧的空格,对于中间和左侧的空格不处理。
substring
public String substring(int beginIndex)
:从指定位截取到最后,0代表第一位。
public String substring(int beginIndex, int endIndex)
:从指定位截取到指定位,包含前者,不包含后者,0代表第一位,共截取 endIndex - beginIndex 位。
String str = "123abc@一二三";
// 截取最后面的4个字符 @一二三
// str.substring(str.length() - 4)
System.out.println(str.substring(str.length() - 4, str.length()));
// 从最后一个@开始截取,但不包含@ 一二三
System.out.println(str.substring(str.lastIndexOf("@") + 1));
split
public String[] split(String regex)
:将一个字符串分割为子字符串,将字符串数组作为结果返回,regex:分割条件,基于正则表达式。
public String[] split(String regex, int limit)
:limit:控制模式应用的次数,因此影响所得数组的长度。
limit大于0,则模式将被最多应用 n-1 次,不会超出分割上限
limit等于0,和split()一样
limit小于0,即使后面有空的串,也会输出到最大
.$|()[{^?*+\
需要注意,- ; , / %
都不用改变。
特殊字符 | 写法 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
^ |
|
@ |
|
# |
|
@# |
|
limit = 0
// 末尾空字符串不被解析
String str = "1,2,3,,,";
String[] st = str.split(",");
for(String s : st){
System.out.println(":" + s);
}
System.out.println(st.length);
// :1
// :2
// :3
// 3
// 最后一个分隔符被分的字符串不为空时,其余空字符串可被解析
String str = "1,2,3,,,6";
String[] st = str.split(",");
for (String s : st) {
System.out.println(":" + s);
}
System.out.println(st.length);
// :1
// :2
// :3
// :
// :
// :6
// 6
limit > 0
String str = "1,2,3,,,";
String[] st = str.split(",", 1000);
for (String s : st) {
System.out.println(":" + s);
}
System.out.println(st.length);
// :1
// :2
// :3
// :
// :
// :
// 6
limit < 0
String str = "1,2,3,,,";
String[] st = str.split(",", -1);
for (String s : st) {
System.out.println(":" + s);
}
System.out.println(st.length);
// :1
// :2
// :3
// :
// :
// :
// 6
replace,replaceAll,replaceFirst
后面的参数替换前面的参数(旧,新)
public String replace(CharSequence target, CharSequence replacement)
:replace的参数是char和CharSequence,即支持字符的替换,也支持字符串的替换。
public String replaceAll(String regex, String replacement)
:replaceAll的参数是regex,基于正则表达式的替换
,因此会对参数进行解析(两个参数均是)。
public String replaceFirst(String regex, String replacement)
:基于正则表达式的替换,只替换第一次出现的。
String str1 = "$18$";
str1.replaceAll("[$]", ""); // 18
str1.replace("$", ""); // 18
String str = "F:\\a\\6.xls";
// 将 \ 替换为 /
System.out.println(str); // F:\a\6.xls
System.out.println(str.replace('\\', '/')); // F:/a/6.xls
System.out.println(str.replace("\\", "/")); // F:/a/6.xls
System.out.println(str.replaceAll("\\\\", "/")); // F:/a/6.xls
indexOf,lastIndexOf,compareTo
public int indexOf(String str)
:从前往后查找参数字符串位于目标字符串的位置,找不到返回 -1 。
public int lastIndexOf(String str)
:从后往前找。
public int compareTo(String anotherString)
:对字符串内容按字典顺序进行大小比较,通过返回的整数值指明当前字符串与参数字符串的大小关系。若当前对象比参数大则返回正整数,反之返回负整数,相等返回0。
public int indexOf(String str, int fromIndex)
:从偏移量开始往后查找。
public int lastIndexOf(String str, int fromIndex)
:从偏移量开始往前查找。
String str1 = "abc";
String str2 = "ABC";
int a = str1.compareTo(str2); // 32
int b = str1.compareToIgnoreCase(str2); // 0
String str3 = "abc0ac0";
int c = str3.indexOf(0); // -1
int d = str3.indexOf("0"); // 3
int e = str3.indexOf("0",4); // 6
int f = str3.lastIndexOf("0"); // 6
int g = str3.lastIndexOf("0",5); // 3
getBytes
public byte[] getBytes(String charsetName) throws UnsupportedEncodingException
:使用指定的字符集将字符串编码为 byte 序列,并将结果存储到新的 byte 数组中,charsetName :字符集名称。
public byte[] getBytes(Charset charset)
:使用指定的字符集将字符串编码为 byte 序列,并将结果存储到新的 byte 数组中。
public byte[] getBytes()
:使用平台默认的字符串编码,并将结果存储到新的 byte 数组中,默认编码格式与file.encoding相同,如果file.encoding为null,默认为"UTF-8"。这种方式十分不友好,特别对于跨系统时,平台编码不一致会导致乱码问题,不建议使用。
equals,equalsIgnoreCase
public boolean equals(Object anObject)
:比较当前字符串和参数字符串的值是否相同
,两个字符串返回true,否则返回false。
public boolean equalsIgnoreCase(String anotherString)
:忽略大小写。
源码:
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;
}
String str = "abc中文";
// true
System.out.println("abc中文".equals(str));
// true
System.out.println("ABc中文".equalsIgnoreCase(str));
matches
public boolean matches(String regex)
:在字符串匹配给定的正则表达式时,返回 true。
String str = new String("www.baidu.com");
System.out.println(str.matches("(.*)baidu(.*)")); // true
System.out.println(str.matches("(.*)google(.*)")); // false
System.out.println(str.matches("www(.*)")); // true
toLowerCase,toUpperCase
public String toLowerCase()
:返回将当前字符串中所有字符转换成小写后的新串。
public String toUpperCase()
:返回将当前字符串中所有字符转换成大写后的新串。
startsWith,endsWith,contains
public boolean startsWith(String prefix, int toffset)
:从偏移量处开始匹配。
public boolean startsWith(String prefix)
:判断字符串是否以指定的前缀开始,如果参数是空字符串,或者等于此 String 对象,则结果为 true。
public boolean endsWith(String suffix)
:判断字符串是否以指定的后缀结束,如果参数是空字符串,或者等于此 String 对象,则结果为 true。
public boolean contains(CharSequence s)
:判断参数是否被包含在字符串中。