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