Java核心类库(二)

本文详细介绍了Java中的String类,包括其不可变性、常量池概念、构造方法及其应用。同时,通过实例展示了面试常见题目,解释了字符串比较和转换方法。此外,还探讨了正则表达式的使用。接着,介绍了可变字符类StringBuilder,包括其构造、方法和应用场景,演示了字符串的插入、删除、替换和反转操作。最后,总结了StringBuilder类的使用要点和面试相关知识点。
摘要由CSDN通过智能技术生成

String类的概述和使用
String类的概念
  • java.lang.String类用于描述字符串,Java程序中所有的字符串字面值都可以使用该类的对象加以描述,如:“abc”。

  • 该类由final关键字修饰,表示该类不能被继承。

  • 从jdk1.9开始该类的底层不使用char[]来存储数据,而是改成 byte[]加上编码标记,从而节约了一 些空间。

  • 该类描述的字符串内容是个常量不可更改,因此可以被共享使用。 如:

    String str1 = “abc”; - 其中"abc"这个字符串是个常量不可改变。 
    str1 = “123”; - 将“123”字符串的地址赋值给变量str1。 - 改变str1的指向并没有改变指向的内容
    

    在这里插入图片描述

常量池

​ 由于String类型描述的字符串内容是常量不可改变,因此Java虚拟机将首次出现的字符串放入常量池中,若后续代码中出现了相同字符串内容则直接使用池中已有的字符串对象而无需申请内存及创建对象,从而提高了性能。

常用的构造方法
方法声明功能介绍
String()使用无参方式构造对象得到空字符序列
String(byte[] bytes, int offset, int length)使用bytes数组中下标从offset位置开始的length个字节来 构造对象
String(byte[] bytes)使用bytes数组中的所有内容构造对象
String(char[] value, int offset, int count)使用value数组中下标从offset位置开始的count个字符来构 造对象
String(char[] value)使用value数组中的所有内容构造对象
String(String original)根据参数指定的字符串内容来构造对象,新创建对象为参 数对象的副本
public class StringConstructorTest {

    public static void main(String[] args) {

        // 1.使用无参方式构造对象并打印
        String str1 = new String();
        // "" 表示空字符串对象,有对象只是里面没有内容
        // null 表示空,连对象都没有
        System.out.println("str1 = " + str1); // ""  自动调用toString方法

        System.out.println("----------------------------------------------------");
        // 2.使用参数指定的byte数组来构造对象并打印
        // 'a' - 97
        byte[] bArr = {97, 98, 99, 100, 101};
        // 使用字节数组中的一部分内容来构造对象,表示使用数组bArr中下标从1开始的3个字节构造字符串对象
        // 构造字符串的思路:就是先将每个整数翻译成对应的字符,再将所有的字符串起来。
        // 98 - 'b'   99 - 'c'  100 - 'd'   => bcd
        String str2 = new String(bArr, 1, 3);
        System.out.println("str2 = " + str2); // bcd

        // 使用整个字节数组来构造字符串对象
        String str3 = new String(bArr);
        System.out.println("str3 = " + str3); // abcde

        System.out.println("----------------------------------------------------");
        // 3.使用字符数组来构造字符串对象
        char[] cArr = {'h', 'e', 'l', 'l', 'o'};
        // 使用字符数组中的一部分内容来构造对象
        // 思路:直接将字符串起来
        String str4 = new String(cArr, 2, 2);
        System.out.println("str4 = " + str4); // ll
        // 使用整个字符数组来构造对象
        String str5 = new String(cArr);
        System.out.println("str5 = " + str5); // hello

        System.out.println("----------------------------------------------------");
        // 4.使用字符串来构造字符串对象
        String str6 = new String("world");
        System.out.println("str6 = " + str6); // world
    }
}
面试题
public class StringExamTest {

    public static void main(String[] args) {

        // 1.请问下面的代码会创建几个对象?分别存放在什么地方?
        //String str1 = "hello";  // 1个对象  存放在常量池中
        //String str1 = new String("helo"); // 2个对象  1个在常量池中,1个在堆区

        // 2.常量池和堆区对象的比较
        String str1 = "hello";  // 常量池
        String str2 = "hello";  // 常量池
        String str3 = new String("hello"); // 堆区
        String str4 = new String("hello"); // 堆区

        System.out.println(str1 == str2);       // 比较地址  true
        System.out.println(str1.equals(str2));  // 比较内容  true
        System.out.println(str3 == str4);       // 比较地址  false
        System.out.println(str3.equals(str4));  // 比较内容  true
        System.out.println(str2 == str4);       // 比较地址  false
        System.out.println(str2.equals(str4));  // 比较内容 true

        System.out.println("------------------------------------------------------------");
        // 3.常量有优化机制,变量没有
        String str5 = "abcd";
        String str6 = "ab" + "cd";  // 常量优化机制  "abcd"
        System.out.println(str5 == str6); // 比较地址  true

        String str7 = "ab";
        String str8 = str7 + "cd"; // 没有常量优化
        System.out.println(str5 == str8); // 比较地址 false


    }
}
常用的成员方法
Stirng类型和数组之间的转换
String toString()返回字符串本身
byte[] getBytes()将当前字符串内容转换为byte数组并返回
char[] toCharArray()用于将当前字符串内容转换为char数组并返回
String类中字符的获取和使用
char charAt(int index)方法charAt用于返回字符串指定位置的字符。
int length()返回字符串字符序列的长度
boolean isEmpty()判断字符串是否为空
String类实现字符串之间大小的比较
int compareTo(String anotherString)用于比较调用对象和参数对象的大小关系
int compareToIgnoreCase(String str)不考虑大小写,也就是’a’和’A’是相等的关系
boolean equals(Object anObject)用于比较字符串内容是否相等并返回
int hashCode()获取调用对象的哈希码值
boolean equalsIgnoreCase(String anotherString)用于比较字符串内容是否相等并返回,不考虑大小写, 如:'A’和’a’是相等
String类中其他方法
String concat(String str)用于实现字符串的拼接
boolean contains(CharSequence s)用于判断当前字符串是否包含参数指定的内容
String toLowerCase()返回字符串的小写形式
String toUpperCase()返回字符串的大写形式
String trim()返回去掉前导和后继空白的字符串
boolean startsWith(String prefix)判断字符串是否以参数字符串开头
boolean startsWith(String prefix, int toffset)从指定位置开始是否以参数字符串开头
boolean endsWith(String suffix)判断字符串是否以参数字符串结尾
String类查找字符
int indexOf(int ch)用于返回当前字符串中参数ch指定的字符第一次出现的 下标
int indexOf(int ch, int fromIndex)用于从fromIndex位置开始查找ch指定的字符
int indexOf(String str)在字符串中检索str返回其第一次出现的位置,若找不到 返回-1
int indexOf(String str, int fromIndex)表示从字符串的fromIndex位置开始检索str第一次出现 的位置
int lastIndexOf(int ch)用于返回参数ch指定的字符最后一次出现的下标
int lastIndexOf(int ch, int fromIndex)用于从fromIndex位置开始查找ch指定字符出现的下标
int lastIndexOf(String str)返回str指定字符串最后一次出现的下标
int lastIndexOf(String str, int fromIndex)用于从fromIndex位置开始反向搜索的第一次出现的下 标。
Stirng中获取子字符串
String substring(int beginIndex, int endIndex)返回字符串中从下标beginIndex(包括)开始到 endIndex(不包括)结束的子字符串
String substring(int beginIndex)返回字符串中从下标beginIndex(包括)开始到字符串结尾的子字符串
正则表达式
概念:

​ 正则表达式本质就是一个“规则字符串”,可以用于对字符串数据的格式进行验证,以及匹配、查 找、替换等操作。该字符串通常使用^运算符作为开头标志,使用$运算符作为结尾标志,当然也可以省略。

规则:
正则表达式说明
[abc]可以出现a、b、c中任意一个字符
[^abc]可以出现任何字符,除了a、b、c的任意字符
[a-z]可以出现a、b、c、……、z中的任意一个字符
[a-zA-Z0-9]可以出现az、AZ、0~9中任意一个字符
.任意一个字符(通常不包含换行符)
\d任意一个数字字符,相当于[0-9]
\D任意一个非数字字符
\s空白字符,相当于[\t\n\x0B\f\r]
\S非空白字符
\w任意一个单词字符,相当于[a-zA-Z_0-9]
\W任意一个非单词字符
X?表示X可以出现一次或一次也没有,也就是0 ~ 1次
X*表示X可以出现零次或多次,也就是0 ~ n次
X+表示X可以出现一次或多次,也就是1 ~ n次
X{n}表示X可以出现恰好 n 次
X{n,}表示X可以出现至少 n 次,也就是>=n次
X{n,m}表示X可以出现至少 n 次,但是不超过 m 次,也就是>=n并且<=m次
相关方法
方法名称方法说明
boolean matches(String regex)判断当前正在调用的字符串是否匹配参数指定的正则表达式规则
import java.util.Scanner;

public class StringRegTest {

    public static void main(String[] args) {

        // 1.定义描述规则的正则表达式字符串并使用变量记录
        // 正则表达式只能对数据格式进行验证,无法对数据内容的正确性进行检查,内容的正确性检查需要后台查询数据库
        // 描述银行卡密码的规则:由6位数字组成
        //String reg = "^[0-9]{6}$";
        //String reg = "[0-9]{6}";
        //String reg = "\\d{6}";
        // 使用正则表达式描述一下QQ号码的规则:要求是由非0开头的5~15位数字组成。
        //String reg = "[1-9]\\d{4,14}";
        //使用正则表达式描述一下手机号码的规则:要求是由1开头,第二位数是3、4、5、7、8中的一位,总共11位
        //String reg = "1[34578]\\d{9}";
        //描述身份证号码的规则:总共18位,6位数字代表地区,4位数字代表年,2位数字代表月,2位数字代表日期, 3位数字代表个人,
        // 最后一位可能数字也可能是X。
        String reg = "(\\d{6})(\\d{4})(\\d{2})(\\d{2})(\\d{3})([0-9|X])";
        // 2.提示用户从键盘输入指定的内容并使用变量记录
        Scanner sc = new Scanner(System.in);
        while(true) {
            //System.out.println("请输入您的银行卡密码:");
            //System.out.println("请输入您的QQ号码:");
            //System.out.println("请输入您的手机号码:");
            System.out.println("请输入您的身份证号码:");
            String str = sc.next();

            // 3.判断用户输入的字符串内容是否满足指定的规则并打印
            if (str.matches(reg)) {
                //System.out.println("银行卡密码的格式正确!");
                System.out.println("输入字符串的格式正确!");
                break;
            } else {
                //System.out.println("银行卡密码的格式错误!");
                System.out.println("输入字符串的格式错误!");
            }
        }
    }
}
其他方法
方法名称相关方法
String[] split(String regex)参数regex为正则表达式,以regex所表示的字符串为分隔 符,将字符串拆分成字符串数组
String replace(char oldChar, char newChar)使用参数newChar替换此字符串中出现的所有参数 oldChar
String replaceFirst(String regex, String replacement)替换此字符串匹配给定的正则表达式的第一个子字符串
String replaceAll(String regex, String replacement)将字符串中匹配正则表达式regex的字符串替换成 replacement
public class StringRegMethodTest {

    public static void main(String[] args) {

        // 1.准备一个字符串对象并打印
        String str1 = "1001,zhangfei,30";
        System.out.println("str1 = " + str1); // 1001,zhangfei,30
        // 2.按照逗号对字符串内容进行切割
        String[] sArr = str1.split(",");
        for (int i = 0; i < sArr.length; i++) {
            System.out.println("下标为" + i + "的字符串是:" + sArr[i]); // 1001 zhangfei 30
        }

        System.out.println("--------------------------------------------------------------");
        // 3.准备一个字符串内容并进行替换
        String str2 = "我的小名叫大帅哥";
        // 将字符串中所有的字符'我'替换为'你'
        String str3 = str2.replace('我', '你');
        System.out.println("str2 = " + str2); // 我的小名叫大帅哥
        System.out.println("str3 = " + str3); // 你的小名叫大帅哥
        // 将字符串中所有的字符'大'替换为'小'
        String str4 = str3.replace('大', '小');
        System.out.println("str4 = " + str4); // 你的小名叫小帅哥
        // 将字符串中所有的字符'小'替换为'大'
        String str5 = str4.replace('小', '大');
        System.out.println("str5 = " + str5); // 你的大名叫大帅哥

        System.out.println("--------------------------------------------------------------");
        // 4.准备一个字符串进行字符串内容的替换
        String str6 = "123abc456def789ghi";
        // 将第一个数字字符串替换为"#"
        String str7 = str6.replaceFirst("\\d+", "#");
        System.out.println("替换第一个字符串后的结果是:" + str7); // #abc456def789ghi
        // 将所有字母字符串替换为"$$$"
        String str8 = str7.replaceAll("[a-z]+", "A");
        System.out.println("str8 = " + str8); // #A456A789A

    }
}
可变字符类
基本概念
  • 由于String类描述的字符串内容是个常量不可改变,当需要在Java代码中描述大量类似的字符串 时,只能单独申请和存储,此时会造成内存空间的浪费。 为了解决上述问题,可以使用java.lang.StringBuilder类和java.lang.StringBuffer类来描述字符序 列可以改变的字符串,如:“ab”。
  • StringBuffer类是从jdk1.0开始存在,属于线程安全的类,因此效率比较低。
  • StringBuilder类是从jdk1.5开始存在,属于非线程安全的类,效率比较高。
构造方法
方法声明方法介绍
StringBuilder()使用无参方式构造对象,容量为16
StringBuilder(int capacity)根据参数指定的容量来构造对象,容量为参数指定大小
StringBuilder(String str)根据参数指定的字符串来构造对象,容量为:16+字符串长度
常用成员方法
方法声明方法介绍
int capacity()用于返回调用对象的容量
int length()用于返回字符串的长度,也就是字符的个数
StringBuilder insert(int offset, String str)插入字符串并返回调用对象的引用,就是自 己。
StringBuilder append(String str)追加字符串
StringBuilder deleteCharAt(int index)将当前字符串中下标为index位置的单个字符 删除
StringBuilder delete(int start,int end)删除字符串 ,将当前字符串中下标为index位置的单个字符 删除 删除字符串,删除一个字符后,后面的字符会补位,下标会发生变化
StringBuilder replace(int start,int end, String str)替换字符串
StringBuilder reverse()字符串反转
返回值
  • StringBuilder的很多方法的返回值均为StringBuilder类型。这些方法的返回语句均为:return this。
  • 由此可见,这些方法在对StringBuilder所封装的字符序列进行改变后又返回了该对象的引用。基于这样设计的目的在于可以连续调用。
package com.nxy.task13;

public class StringBuilderTest {

    public static void main(String[] args) {

        // 1.使用无参方式构造StringBuilder类型的对象并打印容量和长度
        StringBuilder sb1 = new StringBuilder();
        System.out.println("sb1 = " + sb1); // 自动调用toString方法 啥也没有
        System.out.println("容量是:" + sb1.capacity()); // 16
        System.out.println("长度是:" + sb1.length()); // 0

        System.out.println("-----------------------------------------------------------");
        // 2.使用参数指定的容量来构造对象并打印容量和长度
        StringBuilder sb2 = new StringBuilder(20);
        System.out.println("sb2 = " + sb2); // 自动调用toString方法 啥也没有
        System.out.println("容量是:" + sb2.capacity()); // 20
        System.out.println("长度是:" + sb2.length()); // 0

        System.out.println("-----------------------------------------------------------");
        // 3.根据参数指定的字符串内容来构造对象并打印容量和长度
        StringBuilder sb3 = new StringBuilder("hello");
        System.out.println("sb3 = " + sb3); // 自动调用toString方法  hello
        System.out.println("容量是:" + sb3.capacity()); // 16 + 5 = 21
        System.out.println("长度是:" + sb3.length()); // 5

        System.out.println("-----------------------------------------------------------");
        String str1 = new String("hello");
        String str2 = str1.toUpperCase();
        System.out.println("str2 = " + str2); // HELLO
        System.out.println("str1 = " + str1); // hello  字符串本身是个常量不会改变

        // 4.实现向字符串中插入和追加字符串内容
        // 向下标为0的位置插入字符串内容"abcd",也就是向开头位置插入字符串内容
        StringBuilder sb4 = sb3.insert(0, "abcd");
        System.out.println("sb4 = " + sb4); // abcdhello  返回调用对象自己的引用,也就是返回值和调用对象是同一个字符串
        System.out.println("sb3 = " + sb3); // abcdhello
        // 向中间位置插入字符串"1234"
        sb3.insert(4, "1234");
        System.out.println("sb3 = " + sb3); // abcd1234hello
        // 向末尾位置插入字符串"ABCD"
        sb3.insert(sb3.length(), "ABCD");
        System.out.println("sb3 = " + sb3); // abcd1234helloABCD

        System.out.println("-----------------------------------------------------------");
        // 向末尾位置追加字符串内容
        sb3.append("world");
        System.out.println("sb3 = " + sb3); // abcd1234helloABCDworld
        // 当字符串的长度超过了字符串对象的初始容量时,该字符串对象会自动扩容,默认扩容算法是:原始容量*2 + 2 => 21*2 + 2 => 44
        // 底层采用byte数组来存放所有的字符内容。
        // ctrl+alt+左右方向键  表示回到上/下一个位置
        System.out.println("容量是:" + sb3.capacity()); // 44
        System.out.println("长度是:" + sb3.length()); // 22

        System.out.println("-----------------------------------------------------------");
        // 5.实现字符串中字符和字符串的删除
        // 表示删除下标为8的单个字符
        sb3.deleteCharAt(8);
        System.out.println("sb3 = " + sb3); // abcd1234elloABCDworld
        // 使用for循环删除多个字符
        for (int i = 8; i < 12; i++) {
            // 由结果可知:删除一个字符后就跳过一个字符继续删除,因为每当删除一个字符后后面的字符会向前补位,因为下标会发生变化
            //sb3.deleteCharAt(i);
            // 始终删除下标为8的字符
            sb3.deleteCharAt(8);
        }
        System.out.println("删除后的字符串是:" + sb3); // abcd1234ABCDworld

        System.out.println("-----------------------------------------------------------");
        // 删除起始字符串abcd,包含0但不包含4
        sb3.delete(0, 4);
        System.out.println("sb3 = " + sb3); // 1234ABCDworld
        // 删除中间字符串
        sb3.delete(4, 8);
        System.out.println("sb3 = " + sb3); // 1234world
        // 删除末尾字符串
        sb3.delete(4, sb3.length());
        System.out.println("sb3 = " + sb3); // 1234

        System.out.println("-----------------------------------------------------------");
        // 6.实现字符串内容的修改、查找以及反转操作
        // 表示将下标为0这个位置的字符修改为'a'
        sb3.setCharAt(0, 'a');
        System.out.println("修改单个字符后的内容是:" + sb3); // a234
        // 修改"234"为"bcd"
        sb3.replace(1, 4, "bcd");
        System.out.println("修改字符串后的结果是:" + sb3); // abcd
        // 实现查找的功能
        int pos = sb3.indexOf("b");
        System.out.println("从前向后查找的结果是:" + pos); // 1
        pos = sb3.lastIndexOf("b");
        System.out.println("从后向前查找的结果是:" + pos); // 1
        // 实现字符串的反转功能
        sb3.reverse();
        System.out.println("反转后的结果是:" + sb3); // dcba

        System.out.println("-----------------------------------------------------------");
        // 7.笔试考点
        // 考点一:既然StringBuilder类的对象本身可以修改,那么为什么成员方法还有返回值呢?
        // 解析:为了连续调用
        //sb3.reverse().append("1").append("2").insert(0, "3").delete(0, 1).reverse();
        // 考点二:如何实现StringBuilder类型和String类型之间的转换呢?
        //String str3 = sb3.toString();
        //StringBuilder sb5 = new StringBuilder(str3);
        // 考点三:String、StringBuilder、StringBuffer之间效率谁高?排列如何?
        // String < StringBuffer < StringBuilder
    }
}

考点
StringBuilder sb = new StringBuilder("hello");
// 考点一:既然StringBuilder类的对象本身可以修改,那么为什么成员方法还有返回值呢?
// 解析:为了连续调用
sb.reverse().append("1").append("2").insert(0, "3").delete(0, 1).reverse();
// 考点二:如何实现StringBuilder类型和String类型之间的转换呢?
String str = sb.toString();
StringBuilder sb1 = new StringBuilder(str);
// 考点三:String、StringBuilder、StringBuffer之间效率谁高?排列如何?
String < StringBuffer < StringBuilder
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值