Java——String类详解

该文章方法预览:

1.常用方法

1.1字符串构造

常用的三种构造方式:

java 复制代码
    public static void main(String[] args) {
        //使用常量串构造
        String s1 = "hello";

        //直接newString对象
        String s2 = new String("world");

        //使用字符数组进行构造
        char[] array = {'l','o','v','e'};
        String s3 = new String(array);

    }

tips:

1.String是引用类型,内部不存储字符串本身,如下代码:

java 复制代码
    public static void main(String[] args) {
        String s1 = new String("hello");
        String s2 = new String("world");
        String s3 = s1;
    }

调试后发现s1中有四个变量,我们只需关心其中value的值

实例化演示图如下:

s1和s2引用的是不同对象,s1和s3引用的是同一对象

2.在Java中,双引号" "引起来的也是String类型,如下:

java 复制代码
        //打印"hello"字符串的长度
        System.out.println("hello".length());

1.2 String对象的比较

1. == 比较是否引用了同一个对象

tip:对于内置类型,== 比较的是变量中的值;对于引用类型,== 比较的是引用中的地址

java 复制代码
    public static void main(String[] args) {
        String s1 = new String("hello");
        String s2 = new String("hello");
        String s3 = new String("world");
        String s4 = s1;

        System.out.println(s1 == s2);
        System.out.println(s2 == s3);
        System.out.println(s1 == s4);
    }

运行结果:

2. boolean equals(Object anObject)方法:按照字典序比较

字典序:字符大小的顺序

String类重写了父类Object中的equals方法,Object中equals默认按照 == 比较,String重写equals方法后,按照如下规则进行比较:

java 复制代码
    public boolean equals(Object anObject) {
        // 1. 先检测this 和 anObject 是否为同一个对象比较,如果是返回true
        if (this == anObject) {
            return true;
        }

        // 2. 检测anObject是否为String类型的对象,如果是继续比较,否则返回false
        if (anObject instanceof String) {
            // 将anObject向下转型为String类型对象
            String anotherString = (String) anObject;
            int n = value.length;

            // 3. this和anObject两个字符串的长度是否相同,是继续比较,否则返回false
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;

                // 4. 按照字典序,从前往后逐个字符进行比较
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }
java 复制代码
    public static void main(String[] args) {
        String s1 = new String("hello");
        String s2 = new String("hello");
        String s3 = new String("Hello");

        //虽然s1与s2引用的不是同一个对象,但是两个对象中放置的内容相同,因此输出true
        System.out.println(s1.equals(s2));
        
        //s1与s3引用的不是同一个对象,且两个对象中放置内容也不同,因此输出false
        System.out.println(s1.equals(s3));
    }

3. int compareTo(String s) 方法:按照字典序进行比较

与equals方法不同的是,equals返回的是boolean类型,而compareTo返回的是int类型

具体比较方式:

1、先按照字典次序大小比较,如果出现不等的字符,直接返回这两个字符的大小差值

2、如果前n个字符相等(n为两个字符长度最小值),返回值两个字符串的长度差值

java 复制代码
    public static void main(String[] args) {
        String s1 = new String("abc");
        String s2 = new String("ac");
        String s3 = new String("abc");
        String s4 = new String("abcdef");

        System.out.println(s1.compareTo(s2));//不同输出字符差值-1
        System.out.println(s1.compareTo(s3));//相同输出0
        System.out.println(s1.compareTo(s4));//前n个字符完全相同,输出长度差值-3
    }

4. int compareTolgnoreCase(String s) 与compareTo方式相同,但是忽略大小写比较

java 复制代码
    public static void main(String[] args) {
        String s1 = new String("abc");
        String s2 = new String("ac");
        String s3 = new String("ABc");
        String s4 = new String("abcdef");

        System.out.println(s1.compareToIgnoreCase(s2));//不同输出字符差值-1
        System.out.println(s1.compareToIgnoreCase(s3));//忽略大小写,相同输出0
        System.out.println(s1.compareToIgnoreCase(s4));//前n个字符完全相同,输出长度差值-3
    }

1.3 字符串查找

java 复制代码
    public static void main(String[] args) {
        String s = "aaabbbcccaaabbbccc";
        System.out.println(s.charAt(3));
        System.out.println(s.indexOf('c'));
        System.out.println(s.indexOf('c', 10));
        System.out.println(s.indexOf("bbb"));
        System.out.println(s.indexOf("bbb", 10));
        System.out.println(s.lastIndexOf('c'));
        System.out.println(s.lastIndexOf('c', 10));
        System.out.println(s.lastIndexOf("bbb"));
        System.out.println(s.lastIndexOf("bbb", 10));
    }

运行结果:


1.4 转化

1. 数值和字符串转化

java 复制代码
    public static void main(String[] args) {
        //数字转字符串
        String s1 = String.valueOf(1234);
        String s2 = String.valueOf(3.14);
        String s3 = String.valueOf(true);
        String s4 = String.valueOf(new Student("zhangsan",18));
        System.out.println(s1);
        System.out.println(s2);
        System.out.println(s3);
        System.out.println(s4);

        System.out.println("===========");

        //字符串转数字
        int data1 = Integer.parseInt("1234");
        double data2 = Double.parseDouble("3.14");
        System.out.println(data1);
        System.out.println(data2);
    }

其中将对象变为字符串的过程称为序列化

而将字符串变为对象的过程称为反序列化

2. 大小写转换

java 复制代码
    public static void main(String[] args) {
        String s1 = "hello";
        String s2 = "HELLO";
        //小写转大写
        System.out.println(s1.toUpperCase());

        //大写转小写
        System.out.println(s2.toLowerCase());
    }

tip:转换的字符串中不能含有除字母外其他符号

3. 字符串转数组

java 复制代码
    public static void main(String[] args) {
        String s1 = "hello";
        //字符串转数组
        char[] ch = s1.toCharArray();
        for (int i = 0; i < ch.length; i++) {
            System.out.print(ch[i]);
        }

        System.out.println();
        
        //数组转字符串
        String s2 = new String(ch);
        System.out.println(s2);
    }

4. 格式化

java 复制代码
    public static void main(String[] args) {
        String s = String.format("%d-%d-%d",2024,5,20);
        System.out.println(s);//运行结果:2024-5-20
    }

1.5 字符串替换

使用一个指定的新字符串替换掉已有的字符串数据,可用方法如下:

示例:

java 复制代码
    public static void main(String[] args) {
        String str = "helloworld";
        System.out.println(str.replaceAll("l","="));
        System.out.println(str.replaceFirst("l","="));
    }

运行结果:

tips:由于字符串是不可变对象,替换不修改当前字符串,而是产生一个新的字符串


1.6 字符串拆分

可以将一个完整的字符串按照指定的分隔符划分为若干个子字符串,可用方法如下:

示例:

字符串全部拆分:

java 复制代码
    public static void main(String[] args) {
        String str = "hello world hello haha";
        String[] result = str.split(" ");//按照空格拆分
        for(String s : result) {
            System.out.println(s);
        }
    }

/*
运行结果:
hello
world
hello
haha
*/

字符串部分拆分:

java 复制代码
    public static void main(String[] args) {
        String str = "hello world hello haha";
        String[] result = str.split(" ",2);//按照空格拆分为两部分
        for(String s : result) {
            System.out.println(s);
        }
    }

/*
运行结果:
hello
world hello haha
*/

tip:有些特殊字符作为分隔符可能无法正确拆分,需要加上转义,如拆分IP地址:

java 复制代码
    public static void main(String[] args) {
        String str = "192.168.1.1";
        String[] result = str.split("\\.");//需加转义字符
        for(String s : result) {
            System.out.println(s);
        }
    }

tips:

  1. 字符**"|" "*" "+"** 前都需加转义字符 "\\"
  2. 如果是 "\" 那就要写成 "\\\\"
  3. 如果一个字符串中有多个分隔符,可以用**"|"** 作为连字符

示例:多次拆分

java 复制代码
    public static void main(String[] args) {
        String str = "name=zhangsan&age=18";
        String[] result = str.split("&");
        for (int i = 0; i < result.length; i++) {
            String[] temp = result[i].split("=");
            System.out.println(temp[0] + " = " + temp[1]);
        }
    }

/*
运行结果:
name = zhangsan
age = 18
*/

1.7 字符串截取

从一个完整的字符串中截取部分内容,可用方法如下:

示例:

java 复制代码
    public static void main(String[] args) {
        String str = "helloworld";
        System.out.println(str.substring(5)); //从下标位置截取到结尾
        System.out.println(str.substring(0,5));//从0下标位置截取到下标5之前,不包含5坐标
    }

/*
运行结果:
world
hello
*/

tip:Java中大部分带有区间的规则都是左闭右开


1.8 其他操作方法

示例:

trim()方法会去掉字符串开头和结尾的空白字符(空格、换行符、制表符等)

java 复制代码
    public static void main(String[] args) {
        String str = "   hello world   ";
        System.out.println("["+str+"]");
        System.out.println("["+str.trim()+"]");
    }

/*
运行结果:
[   hello world   ]
[hello world]
*/

大小写转换:

java 复制代码
    public static void main(String[] args) {
        String str = "   hello%$$%@#$%world 哈哈哈  ";
        System.out.println(str.toUpperCase());
        System.out.println(str.toLowerCase());
    }

/*
tip:这两个函数只转换字母
运行结果:
   HELLO%$$%@#$%WORLD 哈哈哈  
   hello%$$%@#$%world 哈哈哈 
*/

1.9 字符串的不可变性

String是一种不可改变的对象,字符串中的内容是不可改变的,原因如下:

我们看String的源码:

我们可以看出String类中的字符实际保存在内部维护的value字符数组中

其中第一个final表明该类不可被继承,不是String不可改变的原因

第二个final表明value自身的值不能改变,即不能引用其它字符数组,但是其引用空间中 的内容可以修改,不是String不可改变的原因

String不可改变的真正原因是因为第三点,它由private所修饰,只能在当前类中使用,且并未提供任何get、set方法,因此无法在类外任何地方改变字符串内容

因此只要涉及到String类型的转变,都不是在原有的字符串上进行的修改,而是会产生一个新对象


1.10 字符串修改

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

java 复制代码
    public static void main(String[] args) {
        long start = System.currentTimeMillis();//获取毫秒级时间戳
        String s = "";
        for (int i = 0; i < 10000; i++) {
            s += i;
        }
        long end = System.currentTimeMillis();
        System.out.println(end - start);

        start = System.currentTimeMillis();
        StringBuffer sbf = new StringBuffer("");
        for (int i = 0; i < 10000; i++) {
            sbf.append(i);
        }
        end = System.currentTimeMillis();
        System.out.println(end - start);

        start = System.currentTimeMillis();
        StringBuilder sbd = new StringBuilder();
        for (int i = 0; i < 10000; i++) {
            sbd.append(i);
        }
        end = System.currentTimeMillis();
        System.out.println(end - start);
    }

/*
运行结果:
85
0
0
*/

通过运行结果可以看出在对String类进行修改时,效率是非常慢的,因此要尽量避免对String的直接修改,如果要修改建议尽量使用 StringBuffer 和 StringBuilder

相关推荐
ForgeAI码匠11 小时前
ForgeAdmin|Spring Boot 3 后台框架的自动配置设计:少写配置,多做组合
java·spring boot·后端
tongluowan00711 小时前
Redisson的参数及工作原理
java·redis·lua·分布式锁
小娄~~11 小时前
C语言卷子错题集
c语言·开发语言·数据结构
仙俊红12 小时前
Integer\int对比,equals()\hashcode面试
java·面试·职场和发展
WiChP12 小时前
【V0.1B10】从零开始的2D游戏引擎开发之路
java·数据库·游戏引擎
一然明月12 小时前
qt基本用法
开发语言·qt
云烟成雨TD12 小时前
Spring AI Alibaba 1.x 系列【60】检查点机制原理与全流程剖析
java·人工智能·spring
ForgeAI码匠12 小时前
Maven 多模块项目如何避免越写越乱?Forge Admin 的模块边界实践
java·人工智能·开源·maven
hef28812 小时前
Prism图形设计从入门到精通:外观设置、图层顺序与微调技巧
开发语言
z落落12 小时前
C# 数组 最终完整版全套笔记(一维+多维+交错+引用类型+对象数组)
java·笔记·c#