当前位置: 首页 > news >正文

Java中的String类

Java中String类

  • String类原理
    • 1 String字符串构造
    • 2 字符串常量池(StringTable)
    • 3 字符串存储方式
  • String常用方法
    • 1 String对象的比较
    • 2 字符串查找
    • 3 转化
    • 4 字符串替换
    • 5 字符串拆分
    • 6 字符串截取
    • 6 去除左右两边空格

String类原理

1 String字符串构造

String类提供的构造方法中有好多种,但是常用的就是以下三种

1 使用常量字符串进行赋值

//使用字符串常量进行赋值
String s1 = "hello";
System.out.println(s1);

2 使用new String新对象

//使用new String对象
String s2 = new String("hello");
System.out.println(s2);

3使用字符数组

//将字符数组传给String
char[] array = {'h','e','l','l','o'};
String s3 = new String(array);
System.out.println(s3);

其他的构造方法请参考这个链接

那我们这里创建好了String类型,那其如何存储的呢
请看下面的Java中String的源码
在这里插入图片描述
从String源码中我们可以发下String引用类型,内部不是存储的字符串本身
那究竟是如何存储的呢,这时候就要引入常量池这个概念

2 字符串常量池(StringTable)

池其实就是相当于将字符串放入池中,自己想取出来可以随时取出来,这是非常高效的
想要了解如何存储,首先要知道一个新的内存:字符串常量池
字符串常量池在JVM中是StringTable类,实际上是一个固定的HashTable,这个可以高效的让我们找到字符串数据


3 字符串存储方式

常量字符串进行赋值

public class Test {
    public static void main(String[] args) {
        String s1 = "abc";
        String s2 = "abc";
        System.out.println(s1==s2);
    }
}

运行结果如下
在这里插入图片描述
在这里插入图片描述
这里其实是先将s1字符串的”abc"放入常量池中
这样我们在创建s2字符串的时候,会先在字符串常量池中找有没有”abc",如果存在,就部重复存储,而是将s2和s1指向字符串常量池的同一位置


并且这里的s1==s2两个引用判断是否相等,其实比较的是其地址是否相同,而不是字符串内容是否相同,因为其指向同一内存,所以它们相同,返回true

new String进行对象存储

public class Test {
    public static void main(String[] args) {
        String s1 = new String("abc");
        String s2 = new String("abc");
        System.out.println(s1==s2);
    }
}

运行结果如下
在这里插入图片描述

在这里插入图片描述
创建s1的时候,会先把s1中的”abc"放入常量池中,创建了一个新对象指向这个“abc"
创建s2的时候,这里的”abc"已经放入池中了,但是它又会重新创建一个新对象指向常量池中“abc"


这个和上面的常量字符串进行赋值不同的是,这是会在堆中创建新对象指向字符常量池,因此虽然,它们内容相同,但是地址是不相同的,因为是两个不同的新对象指向了常量池的同一地址,而且这里比较的是地址,所以返回true

String常用方法

1 String对象的比较

==进行比较

public class Test {
    public static void main(String[] args) {
        //普通对象的比较
        int a = 10;
        int b = 20;
        int c = 10;
        System.out.println(a==b);//false
        System.out.println(a==c);//true
        System.out.println("=====================");
        //String类使用==比较的话其实
        //比较的是地址,其实
        String s1 = new String("hello");
        String s2 = new String("hello");

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

这里的String类型进行比较,比较的是地址,所以这里的地址不相同,所以这里的引用比较返回false
运行结果如下
在这里插入图片描述

equals方法比较
这里的方法是一个一个字符进行比较

例如:s1.equals(s2)
用来判断s1和s2内容是否相同
返回值是boolean类型

在JDK17部分源码如下
在这里插入图片描述
例如

public class Test {
    public static void main(String[] args) {
        String s1 = new String("hello");
        String s2 = new String("hello");

        System.out.println(s1 == s2);//比较地址
        System.out.println(s1.equals(s2));//比较内容

    }
}

运行结果如下
在这里插入图片描述
从这里的结果可以看处equals方法的确比较的是内容

compareTof方法比较

与equals方法不同的是,这里的compareTo返回的是int类型
按照顺序从前向后比较,如果出现了不相同的字符,就返回它们俩的差值
如果前面K个字符都相同,K是其中一个字符串的长度,这时返回两字符串长度的差值
相同就返回0

例如

public class Test {
    public static void main(String[] args) {
        String s1 = new String("abc");
        String s2 = new String("abc");
        String s3 = new String("abcdef");
        String s4 = new String("zxd");
        System.out.println(s1.compareTo(s2));
        System.out.println(s1.compareTo(s3));
        System.out.println(s1.compareTo(s4));
    }
}

这里的话,s1是等于s2的返回值为0
s1与s3前面相同,但是s1结尾了,就返回它们俩长度的差值,就是s1的长度减去s3的长度
s1与s4第一个就不相同,就直接返回第一个字符的差值,就是 ’a’-‘z’
运行结果如下
在这里插入图片描述

compareToIgnoreCase比较与compareTo不同的是:其忽略大小写

例如:

public class Test {
    public static void main(String[] args) {
        String s1 = new String("abc");
        String s2 = new String("ABC");
        String s3 = new String("ABCDef");
        System.out.println(s1.compareToIgnoreCase(s2));
        //这里比较的是其字符忽略大小写进行比较
        System.out.println(s1.compareToIgnoreCase(s3));
        //前面字符相同,返回就是它们长度差值,就是-3
    }

}
这里的s1和s2进行比较的是忽略大小写,所以这里返回0
s1与s3进行比较,在s1截止前它们相同,
因此这时返回它们长度差值 3减去6,也就是-3

运行结果如下
在这里插入图片描述

2 字符串查找

char charAt(int index)
功能:是输入下标返回其对应的字符,如果越界访问就会又越界访问异常
返回值:char类型

public class Test {
    public static void main(String[] args) {
        String s = "aaabbbcccdddeefff";
        char s1 = s.charAt(3);
        System.out.println(s1);//对应下标的字母---'b'
    }
}

运行结果如下
在这里插入图片描述
如果下标越界访问就会报错
在这里插入图片描述

indxof
功能: 用来查找指定字符或者字符串第一次出现的位置
返回值:int类型
如果找到返回其下标,字符串返回第一个字符的下标
找不到就返回-

在这里插入图片描述

public class Test {
    public static void main(String[] args) {
        String s = "abcabcabc";
        int ind = s.indexOf('a');
        System.out.println(ind);//不指定位置,从头开始找
        System.out.println(s.indexOf('b',3));//指定位置开始找
        System.out.println(s.indexOf("abc"));
        System.out.println(s.indexOf("abc",3));
        //找不到返回-1
        System.out.println(s.indexOf('d'));
        System.out.println(s.indexOf("abcd"));
    }
}

运行结果如下
在这里插入图片描述

lastIndexOf
和indexof其他相同,唯一不同的是lastIndexOf从后向前找indexof从前向后找
在这里插入图片描述

public class Test {
    public static void main(String[] args) {
        String s = "abcabcabc";
        System.out.println(s.lastIndexOf('a'));
        System.out.println(s.lastIndexOf('a',5));
        System.out.println(s.lastIndexOf("abc"));
        System.out.println(s.lastIndexOf("abc",5));//指定位置从后向前找

        //找不到返回-1
        System.out.println(s.lastIndexOf("bc",0));
    }
}

运行结果如下
在这里插入图片描述

3 转化

toUpperCase()将小写转化为大写
toLowerCase()将大写转化为小写
返回值:String类型

在这里插入图片描述

public class Test {
    public static void main(String[] args) {
        String s1 = "hello";
        String s2 = "HELLO";
        System.out.println(s1.toUpperCase());//转化为大写
        System.out.println(s2.toLowerCase());//转化为小写
    }
}

运行结果如下
在这里插入图片描述

字符串转数组 toCharArray()

public class Test {
    public static void main(String[] args) {
        String s = "hello";
        //字符串转数组
        char[] ch = s.toCharArray();
        for (int i = 0; i < ch.length; i++) {
            System.out.print(ch[i]);
        }
        System.out.println();
        //数组转字符串
        String s1 = new String(ch);
        System.out.println(s1);
    }
}

运行结果如下
在这里插入图片描述

4 字符串替换

String replaceAll(String regex,String replacement)替换自己指定的全部字符
String replaceFirst(String regex,String replacement)替换自己指定第一次出现的那个
返回值:String类型
第一个参数是要修改的字符串
第二个参数是修改成那个字符串

在这里插入图片描述

public class Test {
    public static void main(String[] args) {
        String s1 = "abcabcabc";
        System.out.println(s1.replaceFirst("a","-"));//只改变第一出现的
        System.out.println(s1.replaceAll("a","-"));//改变自己指定所以的
        System.out.println(s1);
    }
}

注意这里并不会对其原本字符串修改,会创建一个新的字符串进行接收
运行结果如下
在这里插入图片描述

5 字符串拆分

String[ ] split(String regex)
在一个指定字符串中如果遇到regex就进行拆分,存储在String类型的数组中
String[ ] split(String regex,int limit)
在一个指定字符串中部分遇到regex进行拆分,拆分为limit份,存储在String类型的数组中

在这里插入图片描述

public class Test {
    public static void main(String[] args) {
        String s = "hello world hello world";
        String[] strings = s.split(" ");//按照空格进行拆分
        //for_each方法打印
        for (String string:strings) {
            System.out.println(string);
        }
        System.out.println("======================");
        String[] strings1 = s.split(" ",2);
        for (String string:strings1) {
            System.out.println(string);
        }
    }
}

这里虽然是拆分,但是原本字符串并没有被修改,这里使用for - each打印
第一个见到” “ 空格就拆分,而第二个是限制分割成两份,与到第一个” “拆分,后面就部拆分了
运行结果如下
在这里插入图片描述
注意:有些分割符合编译器可能无法识别
例如:

public class Test {
    public static void main(String[] args) {
        String s = "12.12.3.4.5";
        String[] strings = s.split(".");
        for (String string:strings) {
            System.out.println(string);
        }
    }
}

在这里插入图片描述
我们相的是将字符串进行 . 进行拆分,但是这里却什么都没有打印,没有分割成功,因为这里的 . 并没有被识别,所以这时候就**要用到转译字符\ **

字符" | “,” * " , " + "都得加上转义字符,前⾯加上 转义字符\
如果以 \ \ 进行分割,这时候就要在前面加上\,这时候的切割字符就变成了\ \ \ \

public class Test {
    public static void main(String[] args) {
        String s = "12.12.3.4.5";
        String[] strings = s.split("\\.");
        for (String string:strings) {
            System.out.println(string);
        }
    }
}

加上\ \ 转义字符就可以成功分割了
运行结果如下
在这里插入图片描述

如果有多个分割字符,就要用” | ”分开

public class Test {
    public static void main(String[] args) {
        String s = "123@163.com";
        String[] strings = s.split("@|\\.");
        for (String s1:strings) {
            System.out.println(s1);
        }
    }
}

运行结果如下
可以看出的确成功了
在这里插入图片描述

6 字符串截取

在这里插入图片描述

String substring(int beginIndex)
String substring(int beginIndex,int endIndex)
一个参数的是,从beginIndex开始截取,直到字符串结尾
两个参数的是,截取下标为[beginIndex,endIndex)的字符串,左闭右开
返回值:String类型

public class Test {
    public static void main(String[] args) {
        String s = "helloworld";
        System.out.println(s.substring(3));
        System.out.println(s.substring(0,5));
    }
}

第一个是从下标为3开始,也就是从第二个l开始打印到结尾
第二个是从下标为[0,5)打印
运行结果如下
在这里插入图片描述

6 去除左右两边空格

在这里插入图片描述
这个会删除左右两边的空格,但是不会删除中间的空格

public class Test {
    public static void main(String[] args) {
        String s = "  hello  world  ";
        System.out.println("["+s+"]");
        //去除左右两边空格
        System.out.println("["+s.trim()+"]");
    }
}

运行结果如下
在这里插入图片描述

到这里就结束了,希望对大家有所帮助,欲知后事如何,请听下回分解

http://www.dtcms.com/a/99715.html

相关文章:

  • 智能巡检机器人:2025年企业安全运维的“数字哨兵“
  • Vue 3 中 slot插槽的使用方法
  • 最大子序和 买股票的最佳时机|| 跳跃游戏
  • 【计算机网络】深入解析TCP/IP参考模型:从四层架构到数据封装,全面对比OSI
  • 面经-项目
  • 革新测试管理 2.0丨Storm UTP统一测试管理平台智能化升级与全流程优化
  • HCIP之VRRP
  • 晶晨S905L3A(B)-安卓9.0-开启ADB和ROOT-支持IPTV6-支持外置游戏系统-支持多种无线芯片-支持救砖-完美通刷线刷固件包
  • memtest86检测内存
  • Anaconda Jupyter 默认启动位置修改
  • 矩阵中对角线的遍历问题【C++】
  • JavaScript运算符与逻辑中断
  • 从零到前沿:2025年人工智能系统性学习路径与最新技术融合指南
  • LangChain 基础系列之文档加载与分割详解:从非结构化数据到知识图谱的关键一步
  • ubuntu24 部署vnc server 使用VNC Viewer连接
  • vLLM 实现加速的原理及举例; vLLM 与 TensorRT 的区别
  • C#里使用C#语言作为脚本运行的方法
  • HarmonyOS NEXT——鸿蒙神策埋点(二)
  • 了解遗传算法的Matlab程序的奥妙之处
  • 【记录自己第一个github 100星项目】采用flask框架构建一个前端页面,进行OpenManus的调用,对OpenManus生成的文件进行预览。
  • 使用Python的pytesseract进行网站模拟登录的脚本,主要针对古诗文网(gushiwen.cn)的登录功能。
  • 第十四届蓝桥杯真题(PWM输出)
  • 【Java/数据结构】二叉树(BinaryTree)(图文版)
  • Ubuntu 系统中安装 Nginx
  • 【study】嵌入式软件工程师学习规划
  • The selected directory is not a valid home for Go SDK
  • [C++] STL - string部分函数小合集
  • 晋升系列6:专项提升
  • PHP 包含:深入理解与最佳实践
  • 软件工程面试题(十二)