String对象的常用方法
package com.itlwc;
public class Test {
public static void main(String[] args) throws Exception {
// 返回字符串中索引2的char值
System.out.println("abcdefg".charAt(2));
// 返回第一次出现索引值
System.out.println("abcdefg".indexOf('c'));
System.out.println("abcdefg".indexOf('c', 3));
System.out.println("abcdefg".indexOf("c"));
System.out.println("abcdefg".indexOf("c", 3));
// 返回最后一次出现索引值
System.out.println("abcdefg".lastIndexOf('c'));
System.out.println("abcdefg".lastIndexOf('c', 3));
System.out.println("abcdefg".lastIndexOf("c"));
System.out.println("abcdefg".lastIndexOf("c", 3));
// 字符串转换为char数组
System.out.println("abcdefg".toCharArray());
char[] cccc = new char["abcdef".length()];
"abcdef".getChars(0, 6, cccc, 0);
System.out.println(cccc);
// char数组转换为String
char[] ccc = { 'a', 'b', 'c' };
System.out.println(new String(ccc));
System.out.println(new String(ccc, 1, 2));
System.out.println(String.copyValueOf(ccc));
System.out.println(String.copyValueOf(ccc, 1, 2));
System.out.println(String.valueOf(ccc));
System.out.println(String.valueOf(ccc,1,2));
// byte数组转型为字符串
System.out.println(new String("123abc".getBytes(), "gb2312"));
// 字符串的长度
System.out.println("abcdefg".length());
// 比较两个字符串内容是否相同
System.out.println("abcdefg".equals("123456"));
// 比较两个字符串内容是否相同不区分大小写
System.out.println("abcdefg".equalsIgnoreCase("ABCDEFG"));
// 返回两个字符串首次出现不同字符时编码值的差值
System.out.println("abcdefg".compareTo("ABCDEFG"));
// 不考虑大小写,按字典顺序比较两个字符串
System.out.println("abcdefg".compareToIgnoreCase("ABCDEFG"));
// 连接字符串
System.out.println("abcdefg".concat("123456"));
// 子串
System.out.println("abcdefg".substring(3));
System.out.println("abcdefg".substring(3, 6));
// 是否包含
System.out.println("abcdefg".contains("abc"));
// 全部包含
System.out.println("abcdefg".contentEquals("abcdefg"));
// 转换为小写
System.out.println("abcdefg".toLowerCase());
// 转换为大写
System.out.println("abcdefg".toUpperCase());
// 去掉前后空格
System.out.println(" abcdefg ".trim());
// 是否以某一个字符串开始
System.out.println("javaSE".startsWith("java"));
// 是否以某一个字符串结尾
System.out.println("student.java".endsWith("java"));
// 字符串是否匹配给定的正则表达式
System.out.println("abcdefg".matches("\\w*"));
// 字符串替换
System.out.println("abcdefg".replace("abc", "123"));
// 正则表达式字符串替换
System.out.println("abcdefg".replaceAll("[a-b]", ""));
// 正则表达式字符串替换
System.out.println("abcdefg".replaceFirst("[a-b]", ""));
//基本数据转型为String
System.out.println(String.valueOf(1));
}
}
/*
打印结果:
c
2
-1
2
-1
2
2
2
2
abcdefg
abcdef
abc
bc
abc
bc
abc
bc
123abc
7
false
true
32
0
abcdefg123456
defg
def
true
true
abcdefg
ABCDEFG
abcdefg
true
true
true
123defg
cdefg
bcdefg
1
*/
String对象
简单语法创建字符串对象
String str1 = "abc";
String str2 = "abc";
创建字符串str1的时候,字符串常量池中没有abc对象,创建abc对象,并让引用str1指向abc对象
创建字符串str2的时候,字符串常量中已经有abc对象,不创建abc对象,让引用str2指向abc对象
new语言创建字符串对象
String str3 = new String("abc");
创建字符串str3的时候,直接在堆中创建内容为abc对象,并让引用str3指向abc对象
再去字符串常量池中查看,是否已经有了abc对象
如果有了,new出来的aaa对象与字符串常量池的对象联系起来
如果没有,在字符串常量池再创建一个aaa对象,并将堆中aaa对象与字符串常量池的对象联系起来
字符串连接
String str1 = "abc";
String str2 = "很简单";
str2 = str1.concat(str2);
分别创建str1,str2对象,将str2内容追加到str1内容后面,
并查找字符串常量池中有没有abc很简单对象,
如果有,则将引用str2指向abc很简单对象,
如果没有,则创建abc很简单对象,并将引用str2指向新创建的abc很简单对象
String str=""与String str=null的区别
前者是没有内容,后者是没有对象
String分隔案例
package com.itlwc;
import java.util.StringTokenizer;
public class Test {
public static void main(String[] args) {
//分隔一
String str = "1987-04-09";
StringTokenizer st = new StringTokenizer(str,"-");
String n = st.nextToken();
String y = st.nextToken();
String r = st.nextToken();
System.out.println(n+"年"+y+"月"+r+"日");
//分隔二
String[] ss = str.split("-");
System.out.println(ss[0]+"年"+ss[1]+"月"+ss[2]+"日");
}
}
/*
打印结果:
1987年04月09日
1987年04月09日
*/
String特殊机制付出的代价
比较两个字符串内容是否相同时,
只需比较两个字符串联系的常量池中对象是否是同一个即可,
这样将内容的比较转换为对引用的比较大大提高了速度
如果没有特殊需求我们尽量避免使用new来创建字符串对象,这样可以节省内存,提高比较效率
字符串的特殊内存机制带来了很多好处,也需要付出一些代价
因为字符串永远不变,在需要大量连接字符串的代码中,性能大幅下降,创建大量无用中间对象
String str = "";
for(int i=0;i<100;i++){
s=s+i
}
将100以内的数字连接成一个字符串,在连接过程中产生了很多中间对象,
每次执行一次连接操作诞生一个新对象丢弃一个老对象,这样会造成性能的急剧下降
StringBuffer基本概念
在大量字符串连接操作时,产生大量无用的中间对象,StringBuffer拟补了String的不足
三个构造器
StringBuffer sb1 = new StringBuffer();
StringBuffer sb2 = new StringBuffer(16);
StringBuffer sb3 = new StringBuffer("a");
StringBuffer方法链
方法链书写格式
引用变量.方法1.方法2.方法3...;
方法链需要注意的问题
非最后一个方法必须有返回类型不能为void,且返回类型不许为引用数据类型
方法链执行步骤
通过引用变量调用方法1
方法1将返回一个对象的引用,然后通过该引用调用指向的对象中的方法2
方法2将返回一个对象的引用,然后通过该引用调用指向的对象中的方法3
以此类推
案例
package com.itlwc;
class MyClass {
public MyClass a() {
System.out.println("成功使用方法链调用了a()");
return this;
}
public MyClass b() {
System.out.println("成功使用方法链调用了b()");
return this;
}
public MyClass c() {
System.out.println("成功使用方法链调用了c()");
return this;
}
public void d() {
System.out.println("成功使用方法链调用了d()");
}
}
public class Test {
public static void main(String[] args) {
// 调用方法链
new MyClass().a().b().c().d();
}
}
/*
打印结果:
成功使用方法链调用了a()
成功使用方法链调用了b()
成功使用方法链调用了c()
成功使用方法链调用了d()
*/
StringBuffer常用方法
package com.itlwc;
public class Test {
public static void main(String[] args) {
StringBuffer sb1 = new StringBuffer("abc");
// 把123追加到sb1末尾
sb1.append("123");
System.out.println(sb1);
// 把---增加到sb1索引为3的位置
sb1.insert(3, "---");
System.out.println(sb1);
// 删除sb1索引3到6之间的字符串
sb1.delete(3, 6);
System.out.println(sb1);
// sb1颠倒
sb1.reverse();
System.out.println(sb1);
// sb1转换为字符串
sb1.toString();
System.out.println(sb1);
// 方法链
sb1.reverse().append("def").insert(0, 0);
System.out.println(sb1);
//修改单个字符的值
sb1.setCharAt(0,'A');
System.out.println(sb1);
}
}
/*
打印结果:
abc123
abc---123
abc123
321cba
321cba
0abc123def
Aabc123def
*/
String vs StringBuffer
String是不可变的类,StringBuffer是可变类
StringBuffer操作字符串要比String效率高很多
案例
package com.itlwc;
public class Test {
public static void main(String[] args) {
Test.getString();
Test.getStringBuffer();
}
public static void getString(){
String tempstr = "lkasjdflkasdjfdsfdsfassdfdsfdssdfdssdf";
long lstart1 = System.currentTimeMillis();
String str ="";
for (int i = 0; i < 5000; i++) {
str+=tempstr;
}
long lend1 = System.currentTimeMillis();
System.out.println("String使用的时间: "+(lend1 - lstart1));
}
public static void getStringBuffer(){
String tempstr = "lkasjdflkasdjfdsfdsfassdfdsfdssdfdssdf";
long lstart1 = System.currentTimeMillis();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < 5000; i++) {
sb.append(tempstr);
}
long lend1 = System.currentTimeMillis();
System.out.println("StringBuffer使用的时间:"+(lend1 - lstart1));
}
}
/*
打印结果:
String使用的时间: 7469
StringBuffer使用的时间:0
*/
StringBuffer VS StringBuilder
都是对字符串进行操作的,构造器方法基本相同
StringBuffer是线程安全的,效率慢一点
StringBuilder是线程不安全的,效率快一点
如果是单线程使用StringBuilder,多线程使用StringBuffer