String

SOBER大约 4 分钟

String

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

String01.java

  1. String 对象用于保存字符串,也就是一组字符序列
  2. 字符串常量对象是用双引号括起的字符序列。例如:"你好”、"12.97"、"boy"等
  3. 字符串的字符使用 Unicode 字符编码,一个字符(不区分字母还是汉字)占两个字节
  4. String 类较常用构造方法(其它看手册)
    • String s1 = new String(); //
    • String s1 = new String(String original); //
    • String s1 = new String(char[] a); //
    • String s1 = new String(char[] a, int startIndex, int count); //

说明

  1. String 实现了 Serializble 接口,所以 String 可以串行化,就是可以在网络上进行传输
  2. String 实现了 Comparable 接口,所以 String 对象可以比较
  3. String 是 final 类,不能被其他类继承
  4. String 有属性 private final char value[]; 用于存放字符串内容
  5. 一定要注意:value 是一个 final 类型,地址不可以修改,值可以修改,即不能指向

二、创建 String 对象的两种方式

1、直接赋值

String s = "yang";

原理:先从常量池查看是否有 "yang" 数据空间,如果有,直接指向;如果没有则重新创建,然后指向。s 最终指向的是常量池的空间地址

2、调用构造器

String s = new String("hspedu");

原理:先在堆中创建空间,里面维护了 value 属性,指向常量池的 "yang" 空间,如果常量池没有 "yang",重新创建,如果有,直接通过 value 指向。最终指向的是堆中的空间地址

3、练习题

  1. 练习题1:以下语句创建了几个对象?画出内存布局图
    String s1 = "hello";
    s1 = "haha"
    // 创建了 2 个 String 对象
    
  2. 练习题2:以下语句创建了几个对象?画出内存布局图
    String s2 = "hello" + "haha";
    // 优化等价 String s2 = "hellohaha";
    // 创建了 1 个 String 对象
    
  3. 练习题3
         /**
          * intern:
          * 当调用 intern 方法时,如果池已经包含与 equals(Object) 方法确定的相当于此 string 对象的字符串,则返回来自池的字符串,否则,此 string 对象将添加到池中,并返回对此 string 对象的引用。
          * b.intern() 方法最终返回的是常量池的地址(对象)
          */
         String a = "hsp"; // 常量池的 ‘hsp’
         String b = new String("hsp"); // 堆中的 ‘hsp’
         System.out.println(a.equals(b)); // true
         System.out.println(a == b); // false
         System.out.println(a == b.intern()); // true
         System.out.println(b == a.intern()); // false
    

三、字符串的特性

1. 特性

  1. String 是一个 final 类,代表不可变的字符序列
  2. 字符串是不可变的。一个字符串对象一旦被分配,其内容是不可变的,

2. 练习题

  1. 以下创建了几个对象
    String a = "hello" + "abc";
    // 编译器会自动优化为 String c = "helloabc"; 所以只会创建一个对象
    
  2. 以下创建了几个对象
    String d = "hello";
    String e = "abc";
    String f = d + e; // 创建了三个对象
    /**
     * String f = d + e; 底层运行逻辑
     * 1. 先创建一个 StringBuilder sb = new StringBuilder();
     * 2. 执行 sb.append(a);
     * 3. 执行 sb.append(b); sb 是在堆中,并且 append 是在原来字符串的基础上追加的
     * 4. String c = sb.toString();
     * 5. 最后其实是 c 指向堆中的对象(String) value[] ---> 池中的 “helloabc”
     * 重要规则:
     * String c1 ="ab" + "cd";
     * 常量相加,看的是池
     * String c1 = a + b;
     * 变量相加,是在堆中
     */
    
  3. 下列程序运行的结果

    string_/string02.java

    public class string02 {
       String str = new String("hsp");
       final char[] ch = {'j', 'a', 'v', 'a'};
       public void change(String str, char ch[]) {
          str = "java";
          ch[0] = 'h';
       }
    
       public static void main(String[] args) {
          string02 ex = new string02();
          ex.change(ex.str, ex.ch);
          System.out.println(ex.str);
          System.out.println(ex.ch);
       }
    }
    

四、String 常见方法

String 类是保存字符串常量的。每次更新都需要重新开辟空间,效率较低,因 此 java 设计者还提供了 StringBuilderStringBuffer 来增强 String 的功能 并提高效率

1. String 类的常见方法应用实例1

  • equals:区分大小写,判断内容是否相等
  • equalslgnoreCase: //忽略大小写的判断内容是否相等
  • length: 获取字符的个数,字符串的长度
  • indexOf: 获取字符在字符串中第1次出现的索引,索引从0开始,如果找不到,返回-1
  • lastlndexOf:获取字符在字符串中最后1次出现的索引,索引从 0 开始,如找不到,返回-1
  • substring:截取指定范围的子串
  • trim: 去前后空格
  • charAt:获取某索引处的字符,注意不能使用 str[index] 这种方式,应该是 str.charAt(index)
  • replace():替换字符串中的字符
  • split:分割字符串
  • concat:拼接字符串
  • toCharArray:转换成字符数组
  • compareTo:比较两个字符串的大小,如果前者大,则返回正数,后者大,则返回负数,如果相等,返回0
  • format:格式化字符串 占位符:%s 字符串,%c 字符,%d 整型,%.2f 浮点型,
    String formatStr = "姓名:%s  年龄:%d  成绩:%.2f"
    String info2 = String.format(formatStr, name, age, score);