String类

一、String类的理解和创建对象

  • 结构剖析

    1. String 对象用于保存字符串,也就是一组字符序列;

    2. 字符串常量对象是用双引号括起来的字符序列。例如:jack"字符串常量;

    3. 字符串的字符使用Unicode字符编码,一个字符(无论汉字还是字母)占两个字节;

    4. String类 有很多构造器,构造器的重载
      常用的有:
      String s1 = new String();
      String s2 = new String(String original);
      String s3 = new String(char[] a);
      String s4 = new String(char[] a,int startIndex,int count);
      String s5 = new String(byte[] b);

    5. String类 实现了接口 Serializable【String 可串行化:可以在网络传输】
      String类 实现了接口 Comparable【String类对象可以比较大小】

      Java String类

    6. String 是 final类,不能被其他类继承;

    7. String类 有属性 private final char value[]; 用于存放字符串内容,即String本质是字符数组;

    8. 一定要注意:value 是一个 final类型,不可以修改:即value数组对象不可以指向新的地址,但是单个字符内容是可以变化的;

  • 创建剖析

    创建String对象的两种方式:

    方式一:直接赋值 String s = "hspedu";

    方式二:调用构造器 String s = new String("hspedu");

    1. 方式一:先从常量池查看是否有 "hsp" 数据空间,如果有直接指向;如果没有则重新创建,然后指向。s 最终指向的是常量池的空间地址。
    2. 方式二:先在堆中创建空间,里面维护了value属性,指向常量池的 "hsp" 空间;如果常量池没有"hsp",重新创建,如果有,直接通过value指向,最终指向的是堆中的空间地址。

    ![jvm的内存:String的内存布局]Java String类

二、字符串的特性

  1. String 是一个final类,代表不可改变的字符序列。

  2. 字符串是不可变的。一个字符串对象一旦被分配,其内容是不可变的。

    //以下语句创建了几个对象
    String s1 = "hello";
    s1 = "haha";
    //创建了2个对象
    
  3. 编译器会判断创建的常量池对象,是否有引用指向。

    //以下语句创建了几个对象
    String a = "hello" + "abc";
    //只有一个对象
    //String a = "hello" + "abc"; => 
    //优化,等价于 String a = "helloabc";
    //1. 编译器不傻,做一个优化,判断创建的常量池对象,是否有引用指向。
    //2. String a = "hello" + "abc"; => String a = "helloabc";
    
  4. String c = a + b; 变量相加,创建过程;

    public class StringExercise {
        public static void main(String[] args) {
            //判断创建了几个对象
            String a = "hello";
            String b = "abc";
            // c 的创建过程:
            //1. 先创建了一个StringBuilder sb =  StringBuilder();
            //2. 执行 sb.append("hello");
            //3. sb.append("abc");
            //4. String c = sb.toString();
            //这里的toString()方法源码:
            /*
             public String toString() {
                return new String(value, 0, count);//这里new了一个String对象
            }
             */
            //最后其实是 c 指向堆中对象(String)value[] -> 池中 "helloabc"
            String c = a + b;
            String d = "helloabc";
            System.out.println(c == d);
        }
    }
    

    底层是StringBuilder sb = StringBuilder();

    sb.append("hello");

    sb.append("abc");

    sb是在堆中,并且append是在原来字符串的基础上追加的。

    重要规则:String c1 = "ab" + "cd"; 常量相加,看的是池。

    String c1 = a + b; 变量相加,是在堆中。

三、 String类的常用方法

  1. intern()方法:

    如果池中已经包含一个等于此String对象的字符串(用equals(Object)方法确定),则返回池中的字符串。否则将此 String对象添加到池中,并返回此String对象的引用。intern()方法最终返回的是常量池的地址(对象)。

  2. equals()方法: 比较内容是否相同,区分大小写;

  3. equalsIgnoreCase()方法: 忽略大小写判断内容是否相等;

  4. length()方法: 获取字符的个数,字符串的长度;

  5. indexOf()方法: 获取字符/子串在字符串对象中第一次出现的索引;

  6. lastIndexOf()方法: 获取字符/子串在字符串对象中最后一次出现的索引;

  7. substring()方法: 截取指定范围内的子串;

public class StringMethod01 {
    public static void main(String[] args) {
        //1. equals 比较内容是否相同,区分大小写
        String str1 = "hello";
        String str2 = "Hello";
        System.out.println(str1.equals(str2));//false
        //2. equalsIgnoreCase 忽略大小写判断内容是否相等
        String username = "johN";
        if("john".equalsIgnoreCase(username)){
            System.out.println("Success!");
        }else{
            System.out.println("Failure!");
        }
        //3. length 获取字符的个数,字符串的长度
        System.out.println("韩顺平".length());
        //4. indexOf 获取字符/子串在字符串对象中第一次出现的索引
        String s1 = "wer@terwe@g";
        int index = s1.indexOf('@');
        int index2 = s1.indexOf("we");
        System.out.println(index);//3
        System.out.println(index2);//0
        //5. lastIndexOf 获取字符/子串在字符串对象中最后一次出现的索引
        s1 = "wer@terwe@g@";
        index = s1.lastIndexOf('@');
        index2 = s1.lastIndexOf("we");
        System.out.println(index);//11
        System.out.println(index2);//7
        //6. substring 截取指定范围内的子串
        String name = "hello,张三";
        //下面name.substring(6) 从索引6开始截取后面所有的内容
        System.out.println(name.substring(6));//截取后面的字符
        //name.substring(0,5) 表示从索引0开始截取,截取到索引5但不包括索引5,[0,5)
        System.out.println(name.substring(2,5));//ll0
    }
}
  1. toUpperCase()方法: 转换成大写;
  2. toLowerCase()方法: 转换成小写;
  3. concat()方法: 拼接字符串;
  4. replace()方法: 替换字符串中的字符;
  5. split()方法: 分割字符串,对于某些分割字符我们需要转义比如 | , \ 等等;
  6. toCharArray()方法: 转换成字符数组;
  7. compareTo()方法: 比较两个字符串的大小;
  8. format()方法: 格式字符串;
public class StringMethod02 {
    public static void main(String[] args) {
        //1. toUpperCase 转换成大写
        String s = "heLLo";
        System.out.println(s.toUpperCase());
        //2. toLowerCase 转换成小写
        System.out.println(s.toLowerCase());
        //3. concat 拼接字符串
        String s1 = "宝玉";
        s1 = s1.concat("林黛玉").concat("薛宝钗").concat("together");
        System.out.println(s1);
        //4. replace 替换字符串中的字符
        //s1.replace() 方法执行后返回的结果,才是替换后的
        //注意对 s1 即原来的字符串无任何影响
        String s2 = s1.replace("林黛玉","jack");
        System.out.println(s2);
        System.out.println(s1);
        //5. split 分割字符串,对于某些分割字符我们需要转义比如 |, \\ 等等
        String poem = "锄禾日当午,汗滴禾下土,谁知盘中餐,粒粒皆辛苦";
        //以 "," 为标准对 poem 进行分割返回一个数组
        String[] split = poem.split(",");
        System.out.println("======分割后内容======");
        for (int i = 0; i < split.length; i++) {
            System.out.println(split[i]);
        }
        poem = "E:\\aaa\\bbb";
        String[] split2 = poem.split("\\\\");
        System.out.println("======分割后内容======");
        for (int i = 0; i < split2.length; i++) {
            System.out.println(split2[i]);
        }
        //6. toCharArray 转换成字符数组
        s = "happy";
        char[] chs = s.toCharArray();
        for (int i = 0; i < chs.length; i++) {
            System.out.println(chs[i]);
        }
        //7. compareTo 比较两个字符串的大小
        //如果前者大,返回正数,后者大,则返回负数,如果相等,返回0
        //源码:
        /*
        public int compareTo(String anotherString) {
        int len1 = value.length;
        int len2 = anotherString.value.length;
        int lim = Math.min(len1, len2);
        char v1[] = value;
        char v2[] = anotherString.value;
        int k = 0;
        while (k < lim) {
            char c1 = v1[k];
            char c2 = v2[k];
            if (c1 != c2) {
                return c1 - c2;
            }
            k++;
        }
        return len1 - len2;
    }
         */
        //(1) 如果 长度相同,并且每个字符也相同,就返回0
        //(2) 如果长度相同或不同,但是在进行比较时,字符有不同,可以区分大小就返回字符间的差值
        //(3) 如果长度不同,前面部分相同,就返回 str1.len - str2.len;
        String a = "jcck";
        String b = "jack";
        System.out.println(a.compareTo(b));//返回值是 'c' - 'a'
        //8. format 格式字符串
        /*
           占位符有:
            %S 字符串 %c 字符 %d 整型 %.2f 浮点型
         */
        String name = "john";
        int age = 10;
        double score = 98.3 / 3;
        char gender = '男';
        //将所有的信息都拼接在一个字符串
        String info = "我的名字是" + name + "年龄是" + age +
                "成绩是" + score + "性别是" + gender;
        System.out.println(info);
        //1. %s %c %d %.2f 称为占位符
        //2. 这些占位符由后面的变量来替换
        //3. %s 表示后面由字符串来替换
        //4. %d 是整数来替换
        //5. %.2f 表示使用小数来替换,替换后,只会保留小数点两位
        //6. %c 使用char 类型来替换
        String formatStr = "我的名字是%s,年龄是%d,成绩是%.2f,性别是%c";
        String info2 = String.format(formatStr,name,age,score,gender);
        System.out.println(info2);
    }
}
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。