IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 【JavaSE】万字详解字符串的秘密。。 -> 正文阅读

[Java知识库]【JavaSE】万字详解字符串的秘密。。

1 字符串的创建

常见的构造 String 的方式

// 方式一
String str = “Hello Bit”;
// 方式二
String str2 = new String(“Hello Bit”);
// 方式三
char[] array = {‘a’, ‘b’, ‘c’};
String str3 = new String(array);

字符串对象结构:
在这里插入图片描述

字符串对象是由一个数组对象和一个hash构成。

注意:java里面字符串最后是没有\n的,String为引用类型

2 字符串比较相等

我们来看一段代码:

public class Test {
    public static void main(String[] args) {
        String str1 = new String("hello");
        String str2 = new String("hello");
        System.out.println(str1 == str2);
    }
}

在这里插入图片描述

这里打印false是因为str1和str2引用分别指向了两个不同的对象,而==相当于是比较两个引用的值也就是两个对象的地址,不同对象的地址必然是不同的,所以会打印false

再来看另一段代码:

public class Test {
    public static void main(String[] args) {
        String str1 = "hello";
        String str2 = "hello";
        System.out.println(str1 == str2);
    }
}

在这里插入图片描述

这里为什么会打印true呢,这里涉及到字符串常量池的问题等会再细讲。

Java 中要想比较字符串的内容, 必须采用String类提供的equals方法:

public static void main(String[] args) {
        String str1 = new String("Hello");
        String str2 = new String("Hello");
        System.out.println(str1.equals(str2));
        // System.out.println(str2.equals(str1)); // 或者这样写也行
    }

在这里插入图片描述
注意事项:
现在需要比较 str 和 “Hello” 两个字符串是否相等, 我们该如何来写呢?
💫上代码

public static void main(String[] args) {
        String str1 = new String("Hello");
        String str = new String("Hello");
        // 方式一
        System.out.println(str.equals("Hello"));
        // 方式二
        System.out.println("Hello".equals(str));
    }

虽然两种方式都能实现功能,但是通常我们会使用方式二,因为,如果str为null,那么方式一就会报错,而方式二不会,所以用方式二更加严谨。

在这里插入图片描述

注意:
“Hello” 这样的字面值常量, 本质上也是一个 String 对象, 完全可以使用 equals 等 String 对象的方法.

3 字符串常量池

字符串常量池是因为Java为String开辟的一块内存缓冲区,为了提高性能同时减少内存开销。在JVM中,字符串常量池由一个hash表实现。默认容量为1009。当字符串常量池中的存储比较多的字符串时,会导致hash冲突,从而每个节点形成长长的链表,导致性能下降。所以在使用字符串常量池时,一定要控制容量。

简单来说字符串常量池就是内存中专门用来存放字符串常量的区域,存放机制是按照哈希函数映射的哈希值来确定存放的位置,当位置重复后就在该位置下用链表的形式将数据串联起来从而方便进行查找。时间复杂度可以达到O(1)。

在这里插入图片描述
我们来通过几个例子来讲下字符串常量池:
🔥1:

public static void main(String[] args) {
        String str2 = "hello" ;
        String str1 = new String("hello");
        System.out.println(str1 == str2);
    }

在这里插入图片描述
接下来我们通过画图来了解整个程序运行过程:
在这里插入图片描述

第一句执行时,会先在字符串常量池查找有没有hello,没有则会在哈希值映射的下标下建立一个节点然后指向hello对象,第二句语句会产生两个对象,首先在常量池检查,发现有hello对象,所以不会在常量池重新创建hello对象,然后会创建一个新对象,同时这个对象会指向hello所在的数组

💡小知识:

若不同字符串被经过哈希函数映射到了相同下标,则会再建立一个节点并链接上一个节点,同时这个新节点会指向新的常量字符串对象。

🔥2:

public static void main(String[] args) {
        String str1 = "11";
        String str2 = new String("1") + new String("1");
        System.out.println(str1 == str2);
    }

在这里插入图片描述

str2字符串会将两个字符串对象拼接成一个StringBuilder对象,然后调用ToString方法转变成String对象然后将地址赋给str2

这里我们也可以看反汇编代码:(在输出文件窗口按住Shift+鼠标右键)
在这里插入图片描述

4 字符串不可变

字符串是一种不可变对象. 它的内容不可改变.
String 类的内部实现也是基于 char[] 来实现的, 它是由final修饰的,所以是不能进行修改的。但是 String 类并没有提供 set 方法之类的来修改内部的字符数组.

在这里插入图片描述

注意:
程序中要少用str+=这种形式的代码,这样只会不断创建新的对象从而导致效率降低。

5 字符、字节、字符串

5.1 字符与字符串

在这里插入图片描述代码示范:

public static void main(String[] args) {
        char[] arr = {'b','i','t'};
        String str1 = new String(arr);
        String str2 = new String(arr,1,2);
        char[] arr1 = str2.toCharArray();
        char c = str1.charAt(1);
        System.out.println(c);
        System.out.println(str1);
        System.out.println(str2);
        System.out.println(Arrays.toString(arr1));

    }

在这里插入图片描述

5.2 字节与字符串

在这里插入图片描述
代码示例:

public static void main(String[] args){
        String str = "hello world";
        byte[] arr = str.getBytes();
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]+" ");
        }
        System.out.println();
        System.out.println(new String(arr));
    }

在这里插入图片描述

总结:

  • byte[] 是把 String 按照一个字节一个字节的方式处理, 这种适合在网络传输, 数据存储这样的场景下使用. 更适合
    针对二进制数据来操作.
  • char[] 是吧 String 按照一个字符一个字符的方式处理, 更适合针对文本数据来操作, 尤其是包含中文的时候.

6 字符串常见操作

6.1 字符串比较

在这里插入图片描述
代码示例:

public static void main(String[] args) {
        String str1 = "hello";
        String str2 = "Hello";
        String str3 = "hello1";
        System.out.println(str1 == str2);
        System.out.println(str1.equals(str2));
        System.out.println(str1.equalsIgnoreCase(str2));
        System.out.println(str1.compareTo(str2));
        System.out.println(str1.compareTo(str3));
    }

在这里插入图片描述

注意:当用comparaTo函数比较的一方长度比另一个字符串短且是另一个字符串的子集,那么会返回两个字符串长度的差值。

原码:
在这里插入图片描述

6.2 字符串查找

在这里插入图片描述
代码示例:

public static void main(String[] args) {
        String str1 = "hello";
        String str = "ll";
        System.out.println(str1.contains(str));
        System.out.println(str1.endsWith("o"));
        System.out.println(str1.lastIndexOf("ll",2));
        System.out.println(str1.indexOf("ll",0));
    }

在这里插入图片描述

注意:
lastIndexOf中的2代表从下标0到查找的字符串长度+2的长度4(即下标0到下标3)这一段字符串的结尾从后往前找。

6.3 字符串替换

在这里插入图片描述
代码示例:

public static void main(String[] args) {
        String str = "hello";
        System.out.println(str.replaceFirst("l","0"));
        System.out.println(str.replaceAll("l","0"));
    }

在这里插入图片描述

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

6.4 字符串拆分

在这里插入图片描述
代码示例:

public static void main(String[] args) {
        String str = "hello this world";
        String[] arr = str.split(" ");
        //将字符串分割为两部分
        String[] arr1 = str.split(" ",2);
        for (String s : arr) {
            System.out.println(s);
        }
        for (String s:arr1) {
            System.out.println(s);
        }
    }

在这里插入图片描述
🔥特殊字符的拆分:

'.' ,' | ',' * ',' + '这类字符则需要在前面加上\才能进行分割。

💫举个栗子:

public static void main(String[] args) {
        String str = "a.sdas.sd.ad.s.ads";
        String[] arr = str.split("\\.");
        for (String s:arr) {
            System.out.println(s);
        }

    }

在这里插入图片描述
多次分割:

public static void main(String[] args) {
        String str = "name=zhangsan&age=18";
        String[] arr = str.split("&");
        for (int i = 0; i < arr.length; i++) {
            String[] arr1 = arr[i].split("=");
            System.out.println(arr1[0]+"  "+arr1[1]);
        }

    }

在这里插入图片描述

6.5 字符串截取

在这里插入图片描述
代码示例:

public static void main(String[] args) {
        String str = "helloworld";
        String tep = str.substring(5);
        String tep1 = str.substring(0,5);
        System.out.println(tep);
        System.out.println(tep1);
    }

在这里插入图片描述

注意:
前闭后开区间的写法, substring(0, 5) 表示包含 0 号下标的字符, 不包含 5 号下标

6.6 其他操作方法

在这里插入图片描述

注意:
1.数组里面是lengh属性,字符串是lengh()方法。
2.“”代表空字符串,但是也是对象,只是长度为0,占内存,在内存中分配一个空间,可以使用Object对象中的方法。
3.大小写转换只能转换字母。

💡实战:编写首字母大写的函数。

public static String firstUpper(String str){
        //保证str不为空字符串和null
        if("".equals(str) || str==null){
            return str;
        }
        if(str.length()>1){
            return str.substring(0,1).toUpperCase()+str.substring(1);
        }
        return str.toUpperCase();
    }
    public static void main(String[] args) {
        String str = "abcde";
        String ret = firstUpper(str);
        System.out.println(ret);
    }

在这里插入图片描述

7 StringBuffer 和 StringBuilder

通常来讲String的操作比较简单,但是由于String的不可更改特性,为了方便字符串的修改,提供StringBuffer和 StringBuilder类。频繁修改字符串的情况考虑使用StingBuffer。

StringBuffer与StringBuilder大部分功能是相似的,但是StringBuffer采用同步处理,属于线程安全操作,所以通常我们会使用StringBuffer。

StringBuffer使用方法:

    public static void main(String[] args) {
        StringBuffer sb = new StringBuffer();
        sb.append("hello").append("bit");
        System.out.println(sb);
        sb.reverse();
        System.out.println(sb);
        sb.delete(3,8).insert(3,"你好");
        System.out.println(sb);

    }

在这里插入图片描述

用StringBuffer 或者 StringBuilder的好处:
1.可以对字符串进行修改。
2.能使用一些字符串所不具备的方法,比如反转,删除,插入字符串。

注意:String和StringBuffer类不能直接转换。如果要想互相转换,可以采用如下原则:

  • String变为StringBuffer:利用StringBuffer的构造方法或append()方法
  • StringBuffer变为String:调用toString()方法

💫实战:消除字符串中重复的字符

public static String deleteS(String str){
        if("".equals(str) || str == null){
            return str;
        }
        StringBuffer sb = new StringBuffer();
        sb.append(str.substring(0,1));
        for (int i = 1; i < str.length(); i++) {
            char c = str.charAt(i);
            if(sb.toString().contains(c+"") == true){
                continue;
            }
            sb.append(c);
        }
        return sb.toString();
    }

    public static void main(String[] args) {
        String str = "adkjasdbdd";
        String ret = deleteS(str);
        System.out.println(ret);
    }

在这里插入图片描述

作者水平有限,若文章有任何问题欢迎私聊或留言,希望和大家一起学习进步!!!
创作不易,再次希望大家👍支持下,谢谢大家🙏

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-12-08 13:41:02  更:2021-12-08 13:41:23 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 6:44:46-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码