【JavaSE 语法】-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>使用常量串构造

说明: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

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

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<s2");
        }else{
            System.out.println("s1==s2");
        }
    }
}

//结果:
s1>s2

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<s2");
        }else{
            System.out.println("compareToIgnoreCase::s1==s2");
        }
    }
}

//结果:
equalsIgnoreCase::s1==s2?true
==========
compareToIgnoreCase::s1==s2

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

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

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

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());
    }
}

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

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

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

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

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

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

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
    }
}

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

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

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

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);
    }
}

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"的字符串。

最后,祝大家中秋快乐!

评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学Java的冬瓜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值