java String类

1.String类

  • 字符串是常量,创建后不可改变
  • 字符串字面值存储在字符串池(方法区)中,可以共享(JDK1.8后方法区合并到堆中)
  • 直接将字面值赋值时,会在常量池中创建对象,并将此变量指向常量池中的字面值对象
  • 通过new来创建String类型的对象时,会创建两个对象,一个在堆中,一个在常量池中,栈中的String类型变量存放堆中对象的地址,堆中对象则指向常量池中的对象
public class StringDemo {
    public static void main(String[] args) {
        String name="hello";// "hello"常量的字面值存放在字符串池中
        System.out.println(name.hashCode());//输出103061
        name="zhangsan";//"zhangsan"赋值给name1,并没有修改数据,而是重新在常量池中开辟了一块新的空间,此时"hello"就成为垃圾
        System.out.println(name.hashCode());//输出3536149
        String name2="zhangsan";
        System.out.println(name2.hashCode());//输出3536149
        System.out.println(name==name2);//true

        //字符串的另一种创建方式new
        String str=new String("java");
        String str2=new String("java");
        System.out.println(str.hashCode());//输出3254818
        System.out.println(str2.hashCode());//输出3254818
        System.out.println(str==str2);//false栈中的值不一样
        System.out.println(str.equals(str2));//true
    }
}

image-20211227235845240

2.String类的常用方法

  • length():返回字符串的长度
  • charAt(int index):返回索引处的字符
  • contains(String str):判断是否包含子字符串str,返回的是boolean类型
public static void main(String[] args) {
    String str="hello, 宋平";
    System.out.println(str.length());//9,空格也算是一个字符
    System.out.println(str.charAt(0));//h
    System.out.println(str.charAt(str.length()-1));//平
    //System.out.println(str.charAt(str.length()));//报错,string越界
    System.out.println(str.contains(" "));//true
    System.out.println(str.contains(","));//true
    System.out.println(str.contains(", "));//true
    System.out.println(str.contains("hello"));//true
    System.out.println(str.contains("he llo"));//false
}
  • toCharArray():将字符串转换成数组
  • indexOf(String str):查找str首次出现的下标,存在则返回该下标,不存在返回-1
  • lastIndexOf(String str):查找str最后一次出现的下标,存在则返回该下标,不存在返回-1
public class StringDemo03 {
    public static void main(String[] args) {
        String str="hello,宋小平,hello,韩信,hello";
        //输出[h, e, l, l, o, ,, 宋, 小, 平, ,, h, e, l, l, o, ,, 韩, 信, ,, h, e, l, l, o]
        System.out.println(Arrays.toString(str.toCharArray()));
        System.out.println(str.indexOf("hello"));//0
        System.out.println(str.indexOf("hello",1));//10
        System.out.println(str.lastIndexOf("hello"));//19
    }
}
  • trim():去掉字符串前后的空格
  • toUpperCase():将小写转换为大写
  • endsWith(String str):判断字符串是不是以str结尾
public class StringDemo04 {
    public static void main(String[] args) {
        String str="   Hello Java  ";
        System.out.println(str.trim());//Hello Java
        System.out.println(str.toUpperCase());//   HELLO JAVA
        System.out.println(str.toLowerCase());//   hello java
        String fileName="hello.java";
        System.out.println(fileName.startsWith("he"));//true
        System.out.println(fileName.endsWith(".java"));//true
    }
}
  • replace(char oldChar,char newChar):将旧字符串替换为新字符串
  • split(String str):对字符串做拆分
  • equals和compareTo:compareTo是比较的字符串的大小(字典表中的位置:前一个减去后一个),如果两个字符串的第一个字符相等,则用其后面的进行比较,如果其中一个字符串是从第一位开始和另一个字符串皆相等,但长度不同,返回的结果为第一个字符串的长度减去第二个字符串的长度
  • equalsIgnoreCase(String str):忽略大小写比较
public class StringDemo05 {
    public static void main(String[] args) {
        String str="hello,宋小平,hello,韩信,hello";
        //你好,宋小平,你好,韩信,你好
        System.out.println(str.replace("hello", "你好"));
        String[] st=str.split(",");
        for (String a: st) {
            System.out.println(a);
        }

        System.out.println("--------补充----------");
        String s1="hello";
        String s2="HELLO";
        System.out.println(s1.equalsIgnoreCase(s2));//true忽略大小写比较
        String s3="abc";//a在ASSIC码中的编码位置为97
        String s4="xyz";//x在ASSIC码中的编码位置为120
        System.out.println(s3.compareTo(s4));//返回97-120=-23
        //第一位都是a,则比较下一位
        String s5="abc";//b在ASSIC码中的编码位置为98
        String s6="ayz";//y在ASSIC码中的编码位置为121
        System.out.println(s3.compareTo(s4));//返回98-121=-23
        //下面这种情况,则用长度来进行比较
        String s7="abc";//前三位这s8的一样,则用长度来比较,长度为3
        String s8="abcdef";//长度为6
        System.out.println(s7.compareTo(s8));//返回3-6=-3
    }
}

3.StringBuffer和StringBuilder

因为String的不可变性,在操作过程中可能会出现无用的垃圾;同时 ,每次操作的时候都会产生一个新的字符串,效率相对低。

针对以上问题,sun公司开发出StringBuffer类(JDK1.0提供),是String的增强类,可变长字符串,相对于StringBuilder来说 ,运行效率低,线程安全。

StringBuilder可变长字符串,jdk1.5提供,运行效率比StringBuffer高,线程不安全,单线程首选。

StringBuffer

/*
* StringBuffer and StringBuilder
* difference with String:
* 1、比String效率高
* 2、比String节省内存
* */
public class StringBufferAndBuilderDemo {
    public static void main(String[] args) {
        StringBuffer sb=new StringBuffer();
        //append,追加
        sb.append("我爱");
        sb.append("宋");
        sb.append("+小狗");
        System.out.println(sb.toString());//我爱宋+小狗
        //insert,根据索引插入
        sb.insert(0,"哈哈");
        sb.insert(1,"?");
        System.out.println(sb.toString());//哈?哈我爱宋+小狗
        //replace,从索引start开始替换,不取end
        sb.replace(1,2,"韩小信");
        System.out.println(sb.toString());//哈韩小信哈我爱宋+小狗
        //delete,根据索引删除
        sb.delete(8,9);
        System.out.println(sb.toString());//哈韩小信哈我爱宋小狗
        //翻转
        sb.reverse();
        System.out.println(sb.toString());//狗小宋爱我哈信小韩哈
        //清空
        sb.delete(0,sb.length());
        System.out.println(sb.toString());
    }
}

StringBuilder的功能方法和StringBuffer几乎一样,效率高,但线程不安全,单线程中使用StringBuilder

验证:

/***
 * 对String、StringBuffer、StringBuilder的效率进行验证
 */
public class StringVertifyDemo {
    public static void main(String[] args) {
//        long start1=System.currentTimeMillis();//返回当前时间
//        String str1="";
//        for (int i = 0; i < 99999; i++) {
//            str1+=i;
//        }
//       //System.out.println(str);
//        long end1=System.currentTimeMillis();
//        System.out.println("用时:"+(end1-start1));//22177ms

        //测试StringBuffer和StringBuilder时要注解掉上面的Sting,否则可能会受到常量池中缓存的影响
        long start2=System.currentTimeMillis();//返回当前时间
        StringBuffer str2=new StringBuffer();
        for (int i = 0; i < 999999; i++) {
            str2.append(i);
        }
        //System.out.println(str);
        long end2=System.currentTimeMillis();
        System.out.println("用时:"+(end2-start2));//76ms


        long start3=System.currentTimeMillis();//返回当前时间
        StringBuilder str3=new StringBuilder();
        for (int i = 0; i < 999999; i++) {
            str3.append(i);
        }
        //System.out.println(str);
        long end3=System.currentTimeMillis();
        System.out.println("用时:"+(end3-start3));//37ms
    }
}
posted @ 2022-01-12 18:56  是韩信啊  阅读(48)  评论(0编辑  收藏  举报