• Java-String类


    一、String的常用方法

    1、字符串构造

    public class String_1 {
        public static void main(String[] args) {
            //1、使用常量串构造
            String s1 = "happy";
                                                                                          
            //2、使用new String对象
            String s2 = new String("happy");
    
            //3、使用字符数组构造
            char[] cs = {'h','a','p','p','y'};
            String s3 = new String(cs);
    
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    1>使用常量串构造

    说明:String s1 = “happy”;其中s1表示引用变量,在栈上happy为字符串常量在常量池

    2>new String对象

    说明:String s2 = new String(“happy”);其中s2是引用变量,在栈上,s2引用的对象在堆上,这个对象有value值和hash值value为引用常量"happy"的字符数组

    3>字符数组构造

    说明:char cs = “happy”;String s3 = new String(cs);

    注意:字符串的存储

    Java中字符串的存储方式

    2、String对象的比较

    2.1、== 比较是否引用同一个对象

    说明:相当于比较是否为同一个地址

    public class String_1 {
        public static void main(String[] args) {
            String s1 = new String("hello");
            String s2 = new String("hello");
            String s3 = s1;
    
            System.out.println("s1==s2?"+(s1==s2));
            System.out.println("s1==s3?"+(s1==s3));
        }
    }
    
    //结果:
    s1和s2引用同一个对象?false
    s1和s3引用同一个对象?true
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    2.2、boolean equals()方法比较是否相等

    说明:String类重写了其父类Object的equals方法,使其功能变为比较字符串是否相等,而不是比较地址。

    public class String_1 {
        public static void main(String[] args) {
            String s1 = new String("world");
            String s2 = new String("world");
            String s3 = s1;
    
            System.out.println("s1等于s2?"+s1.equals(s2));
            System.out.println("s1等于s3?"+s1.equals(s3));
        }
    }
    
    //结果:
    s1等于s2?true
    s1等于s3?true
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    2.3、int compareTo()比较大小

    说明:String类实现了comparable接口,重写了compareTo方法

    public class String_1 {
        public static void main(String[] args) {
            String s1 = new String("world");
            String s2 = new String("apple");
    
            if(s1.compareTo(s2)>0) {
                System.out.println("s1>s2");
            }else if(s1.compareTo(s2)<0){
                System.out.println("s1);
            }else{
                System.out.println("s1==s2");
            }
        }
    }
    
    //结果:
    s1>s2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    2.4、IgnoreCase()忽略大小写比较

    说明:boolean equalsIgnoreCase()和int compareIgnoreCase()都是String类自己的方法。
    1、 s1.equalsIgnoreCase(s2)=>忽略大小写比较s1,s2是否相等
    2、s1.compareToIgnoreCase(s2)=>忽略大小写比较s1,s2大小

    public class String_1 {
        public static void main(String[] args) {
            String s1 = new String("apple");
            String s2 = new String("Apple");
            //1、equalsIgnoreCase
            System.out.println("equalsIgnoreCase::s1==s2?"+s1.equalsIgnoreCase(s2));
            System.out.println("==========");
            //2、compareIgnoreCase
            if(s1.compareToIgnoreCase(s2)>0) {
                System.out.println("compareToIgnoreCase::s1>s2");
            }else if(s1.compareToIgnoreCase(s2)<0){
                System.out.println("compareToIgnoreCase::s1);
            }else{
                System.out.println("compareToIgnoreCase::s1==s2");
            }
        }
    }
    
    //结果:
    equalsIgnoreCase::s1==s2?true
    ==========
    compareToIgnoreCase::s1==s2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    3、字符串查找

    3.1、查找字符串里字符位置

    说明:
    1、char charAt(int index)//查找目标下标的字符,除它之外都是查字符的下标
    2、int indexOf(int ch)
    3、int indexOf(char ch, int fromIndex)
    4、int lastIndexOf(int ch)
    5、int lastIndexOf(int ch, int fromIndex)

    public class String_1 {
        public static void main(String[] args) {
            String s = "aabbbcccbbb";
    
            //1、char charAt(int index)//查找目标下标的字符,除它之外都是查下标
            System.out.println(s.charAt(2));//b
    
            //2、int indexOf(int ch)  //将字符转换为ASCII码再运算
            System.out.println(s.indexOf('b'));//2
    
            //3、int indexOf(char ch, int fromIndex) //从fromIndex下标开始从前往后找
            System.out.println(s.indexOf('b', 5));//8
    
            //4、int lastIndexOf(int ch)
            System.out.println(s.lastIndexOf('c'));//7
    
            //5、int lastIndexOf(int ch, int fromIndex)//从fromIndex下标开始从后往前找
            System.out.println(s.lastIndexOf('b', 7));//4
    
        }
    }
    //结果
    b
    2
    8
    7
    4
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    3.2、查找子串位置

    说明:
    1、int indexOf(String str)
    2、int indexOf(String str, fromIndex)
    3、int lastIndexOf(String str)
    4、int lastIndexOf(String str, formIndex)

    public class String_1 {
        public static void main(String[] args) {
            String s = "aabbcccbbb";
    
            //1、int indexOf(String str)
            System.out.println(s.indexOf("bb"));//2
    
            //2、int indexOf(String str, fromIndex)
            System.out.println(s.indexOf("bb", 4));//7
    
            //3、int lastIndexOf(String str)
            System.out.println(s.lastIndexOf("cc"));//5
    
            //4、int lastIndexOf(String str, formIndex)
            // 从fromIndex从后往前向前找,
            // 第一个字母符合后向后接着比较剩下的字母,若剩下的也相等,则返回子串第一个字母在母串中的下标,
            // 否则继续查找,如果遍历完都没有就返回-1
            System.out.println(s.lastIndexOf("bb", 3));//2
        }
    }
    
    //结果:
    2
    7
    5
    2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    4、转化

    4.1、数值和字符串转化

    说明:
    其它=》字符串:String.valueOf()valueOf()是String类的静态方法,所以用类名访问
    字符串=》其它:其它类型.parse…()

    public class String_1 {
        public static void main(String[] args) {
            //1、数字转换为字符串
            String s1 = String.valueOf(1234);
            String s2 = String.valueOf(12.34);
            String s3 = String.valueOf(true);
            //这个相当于toString
            String s4 = String.valueOf(new Student("Hanmeimei", 18));
            System.out.println(s1+"\n"+s2+"\n"+s3+"\n"+s4);
            System.out.println("===================");
    
            //2、字符串转换为数字
            int a = Integer.parseInt(s1);
            double d = Double.parseDouble(s2);
            boolean b = Boolean.parseBoolean(s3);
            System.out.println(a+"\n"+d+"\n"+b);
            //Student类型转换为字符串后,不能再次转换为Student类型。
    
        }
    }
    
    class Student {
        public String name;
        public int age;
    
        public Student(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        @Override
        public String toString() {
            return "Student{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    }
    
    //结果:
    1234
    12.34
    true
    Student{name='Hanmeimei', age=18}
    ===================
    1234
    12.34
    true
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    4.2、大小写转换

    说明:
    小=》大:字符串.toUpperCase()
    大=》小:字符串.toLowerCase()

    public class String_1 {
        public static void main(String[] args) {
            String s1 = "help";
            String s2 = "HELLO";
    
            System.out.println(s1.toUpperCase());
            System.out.println(s2.toLowerCase());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    4.3、字符串和数组互相转换

    1、字符串=》数组:字符串.toCharArray()
    2、数组=》字符串:String 名 = new String(数组名)

    public class String_1 {
        public static void main(String[] args) {
            String s = "hello";
            char[] chars = s.toCharArray();
            //1、字符串=》数组
            for (int i=0;i<s.length();i++){ //s是字符串length后面加(),而chars是数组,求长度不加括号
                System.out.print(chars[i]);
            }
            System.out.println("\n=============");
    
            //2、数组=》字符串
            String s1 = new String(chars);
            System.out.println(s1);
        }
    }
    
    //结果:
    hello
    =============
    hello
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    4.4、format格式化

    String s = String.format(“%d-%d-%d”,2022,9,9)

    public class String_1 {
        public static void main(String[] args) {
            String s = String.format("%d-%d-%d",2022,9,9);
            System.out.println(s);
        }
    }
    
    //结果
    2022-9-9
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    5、字符串替换

    说明:
    1、字符串.replaceAll()
    2、字符串.replaceFirst()

    public class String_1 {
        public static void main(String[] args) {
            String s = "HelloWorld";
            String s1 = s.replaceAll("l","x");
            System.out.println(s1);
    
            String s3 = s.replaceFirst("l","x");
            System.out.println(s3);
        }
    }
    
    //结果:
    HexxoWorxd
    HexloWorld
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    6、字符串拆分

    6.1、简单的split分割

    1、String[] strings = 字符串.split(“分割符”)
    2、String[] strings = 字符串.split(“分割符, 分成字符串成员个数”)

    public class String_1 {
        public static void main(String[] args) {
            String s1 = "My name is LiHua";
            //1、String[] strings = 字符串.split("分隔符")
            String[] strings = s1.split(" ");
            for (int i = 0; i < strings.length; i++) {
                System.out.println(strings[i]);
            }
    
            System.out.println("===================");
            //2、String[] strings = 字符串.split("分隔符, 分成字符串成员个数")
            String[] strings1 = s1.split(" ",3);
            for (int i = 0; i < strings1.length; i++) {
                System.out.println(strings1[i]);
            }
        }
    }
    
    //结果:
    My
    name
    is
    LiHua
    ===================
    My
    name
    is LiHua
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    6.2、转义分割和多重分割

    说明:
    1、用 "\分隔符"分割".“,”+“,”*“,”|"等符号
    2、用 “\\“分割”\”
    3、多重分割用 “分隔符 | 分隔符”

    public class String_1 {
        public static void main(String[] args) {
            //1、用"\\符号"分割  ".","+","*","|"等符号
            String s1 = "192.169.1.1";
            String[] strings1 = s1.split("\\.");
            for (int i = 0; i < strings1.length; i++) {
                System.out.println(strings1[i]);
            }
    
            System.out.println("===================");
            //2、"\\\\"分割"\\"
            String s2 = "abc\\bde|hf+mb"; //第一个\转义第二个\使第二个成为字符
            String[] strings2 = s2.split("\\\\");
            for (int i = 0; i < strings2.length; i++) {
                System.out.println(strings2[i]);
            }
    
            System.out.println("===================");
            //3、多重分割用"|"
            String s3 = "zhang=San&wang=wu";
            String[] strings3 = s3.split("=|&");
            for (int i = 0; i < strings3.length; i++) {
                System.out.println(strings3[i]);
            }
        }
    }
    
    //结果:
    192
    169
    1
    1
    ===================
    abc
    bde|hf+mb
    ===================
    zhang
    San
    wang
    wu
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    7、字符串截取

    说明:
    1、字符串.subString(int beginIndex)
    2、字符串.subString(int beginIndex, int endIndex),其中截取片段不包括endIndex,遵循左闭右开

    public class String_1 {
        public static void main(String[] args) {
            //1、字符串.subString(int beginIndex)
            String s1 = "hello world";
            String cs1 = s1.substring(1);
            System.out.println(cs1);
    
            //2、字符串.subString(int beginIndex, int endIndex)
            //其中截取片段不包括endIndex,遵循左闭右开
            String cs2 = s1.substring(1,4);
            System.out.println(cs2);
        }
    }
    
    //结果
    ello world
    ell
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    8、其它操作方法

    8.1、求字符串长度length()

    说明:
    求字符串长度字符串.length()
    求数组长度:==数组名.length ==

    8.2、trim()省略空格

    说明:
    trim()会去掉字符串开头和结尾的空白字符(空格, 换行, 制表符等)

    二、字符串常量池

    1、常量池介绍

    说明:
    1、在Java程序中,类似于1,2,3.14,“hello”,等字面类型常量经常使用,为了使程序运行更快,更节省内存,Java为8种数据类型String类都提供了常量池。
    2、为了运行效率和节省空间,java中还引入了:

    • .Class文件常量池:每个.Java源文件编译后生成.Class文件中会保存当前类中的字面常量以及符号信息
    • 运行时常量池:在.Class文件被加载时,.Class文件中的常量池被加载到内存中称为运行时常量池。

    2、String对象内存深究

    2.1、直接使用字符串常量进行赋值

    一、例子:
    String s1 = “hello”;
    String s2 = “hello”;
    二、内存:
    1、直接使用字符串常量进行赋值

    三、注意:

    • 在字节码文件加载时,"hello"常量串已经创建好了,并保存在字符串常量池中
    • 当使用String s1 = “hello”;创建对象时,先在字符串常量池中查找该常量串,找到后,就将字符串(对象)引用赋值给s1。

    2.2、new创建String类对象

    一、例子:
    String s1 = new String(“hello”);
    String s2 = newString(“hello”);
    二、内存:
    第1步:执行第一句前,先检查字符串常量池没有"hello",所以先创建对象
    执行前检查字符串是否在字符串常量池

    第2步:执行String s1 = new String(“hello”)。先检查在常量池中已经存储"hello"字符串,找到后把这个字符串存放的value里的数组"hello"的地址传给new String的value。String s2 = new String(“hello”)操作一样。
    开始执行创建对象

    三、在IDEA中证明:

    注意:所有对象指向同一个数组

    IDEA中展示

    2.3、intern方法

    说明:intern()是一个native方法(底层用C/C++实现,看不到源代码)
    作用:手动将创建的String对象添加到字符串常量池中

    字符串.intren()使用

    解释:
    如上面代码,调用s1.intern()后,s1就在字符串常量池。s2就直接找到s1创建好的数组,从而提高效率和节省空间

    3、面试题

    请解释String类中两种对象实例化的区别

    一、String str = “hello”;

    解释:
    只开辟一块堆内存空间(有2个对象,1个数组和1个字符串对象),保存在字符串常量池中,然后str共享常量池中的String对象

    二、String str = new String(“hello”);

    解释:
    开辟两块堆内存空间(3个对象,1个数组对象,2个字符串对象),字符串"hello"保存在字符串常量池中,然后用常量池中的String对象给新开辟的String对象赋值

    三、String str = new String(new char[]{‘h’,‘e’,‘l’,‘l’,‘o’})

    解释:
    一、先在堆上创建一个String对象(3个对象,2个数组对象,1个字符串对象),二、然后重新开辟并创建”hello“的字符串,三、再利用copyOf重新开辟数组空间并拷贝,四、最后将new的参数字符串数组的地址拷贝到String对象value中

    三、字符串的不可变性

    1、字符串的不可变性

    字符串的不可变性

    1、不可变性

    1>String类下修饰它的final表示:String类不能被继承。
    2>private final char value[]中的final表示:自身的值不能改变(与C语言中的const相似)即不能引用其他数组,但是引用空间中的内容可以修改。private是限制了它不能改变的根本原因

    2、修改字符串

    注意:尽量避免直接对String类型对象进行修改,因为String类是不能修改的,所有的修改都会创建新的对象,效率非常低下

    如下代码:

    public class String_2 {
    public static void main(String[] args) {
            String s = "hello";
            s += " world";
            System.out.println(s); // 输出:hello world
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    2、StringBuilder和StringBuffer修改字符串

    说明:
    StringBuilder和StringBuffer都是对原来的字符串进行操作

    2.1、append方法:

    public class String_2 {
        public static void main(String[] args) {
            StringBuilder s1 = new StringBuilder("hello");
            s1.append(" world");
    
            System.out.println(s1);
        }
    }
    
    //结果:
    hello world
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    2.2、reverse方法:

    public class String_2 {
        public static void main(String[] args) {
            StringBuilder s1 = new StringBuilder("hello");
            System.out.println(s1); 
            StringBuilder s2 = s1.reverse();
            System.out.println(s2);
        }
    }
    
    //结果:
    hello
    olleh
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    2.3、可变字符串IDEA证明

    public class String_2 {
        public static void main(String[] args) {
            StringBuilder sb1 = new StringBuilder("hello");
            StringBuilder sb2 = sb1;
    
            sb1.append(" world"); // hello world
            System.out.println(sb1==sb2);
        }
    }
    
    //结果:
    true
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    3、可变字符串和不可变字符串之间的转换

    说明:
    1、String=》StringBuilder:利用StringBuilder构造方法或append()方法
    2、StringBuilder=》String:调用toString()方法

    public class String_2 {
    public static void main(String[] args) {
            //1、String=》StringBuilder
            StringBuilder s1 = new StringBuilder("hello");
            s1.append(" world");
    
            //2、StringBuilder=》String
            String s2 = s1.toString();
            System.out.println(s1);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    4、面试题

    题一、String、StringBuilder、Stringbuffer的区别

    • 1、String的内容不能修改StringBuffer和StringBuilder的内容可以修改
    • 2、StringBuffer和StringBuilder的大部分功能是相似的
    • 3、StringBuffer是多线程操作,采用同步处理,属于线程安全操作,StringBuilder未采用同步处理,属于线程不安全操作

    题二、以下各创建了多少个字符串对象
    1、String str = new String(“ab”);
    2、String str = new String(“a”) + new String(“b”);

    • 1、两个对象,一个是常量池中共用字符串,一个是new的字符串
    • 2、六个对象,两个常量池共用字符串,两个new的字符串,一个"a"+"b"的字符串,一个返回new “a”+"b"的字符串。

    最后,祝大家中秋快乐!

  • 相关阅读:
    Apollo之Docker部署
    【分享】集简云新功能:集简云浏览器机器人,将任意网站页面转换为API连接器
    Android 基础知识4-1 用户界面简介VIewGroup、Onclick事件处理
    E056-web安全应用-File Inclusion文件包含漏洞进阶
    C#时间使用整理,DateTime 使用整理
    ant-design-vue table 同时勾选或者取消勾选某字段值相同的数据
    关于到年底日常生活的工作计划
    Unity项目升级支持HDRP管线实践
    轻松掌握组件启动之MongoDB(上):高可用复制集架构环境搭建
    《逆向工程核心原理》学习笔记(六):高级逆向分析技术
  • 原文地址:https://blog.csdn.net/m0_63979882/article/details/126775776