【Java SE】带你在String类世界中遨游!!!

2023-11-30 00:20
文章标签 java se 世界 string 遨游

本文主要是介绍【Java SE】带你在String类世界中遨游!!!,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在这里插入图片描述
🌹🌹🌹我的主页🌹🌹🌹
🌹🌹🌹【Java SE 专栏】🌹🌹🌹
🌹🌹🌹上一篇文章:带你走近Java的抽象类与接口🌹🌹🌹

文章目录

  • 1. String类的重要性
    • 2. String类常用方法
    • 2.1 字符串构造
    • 2.2 String对象的比较
    • 2.3 字符串查找
    • 2.4 转化
    • 2.5 字符串替换
    • 2.6 字符串拆分
    • 2.7 字符串截取
    • 2.8 字符串的不可变性
    • 2.11 字符串修改
      • 3.StringBuilder和StringBuffer
    • 3.1 StringBuilder的介绍

1. String类的重要性

在C语言中已经涉及到字符串了,但是在C语言中要表示字符串只能使用字符数组或者字符指针,可以使用标准库提供的字符串系列函数完成大部分操作,但是这种将数据和操作数据方法分离开的方式不符合面相对象的思想,而字符串应用又非常广泛,因此Java语言专门提供了String类。

2. String类常用方法

2.1 字符串构造

String类提供的构造方式非常多,常用的就以下三种:
1.使用常量串构造,也称字符串赋值

String str = "hello";

2.直接newString对象

 String str1 = new String("hello,world");

3.使用字符数组进行构造

char[] array = {'1','2','3','4'};
String str2 = new String(array);

将数组名作为形参传到String的构造函数之后,调用了数组的复制方法copyof,然后返回的类型是String类型。
在这里插入图片描述
【注意】

  1. String是引用类型,内部并不存储字符串本身,在String类的实现源码中,String类实例变量如下:
    在这里插入图片描述
    字符串中的内容实际存储在value[]数组当中。

字符串是引用类型,并不直接存储字符串的内容,而是存储的是引用变量的地址。
以下代码和画图演示可以证明:

 public static void main(String[] args) {My_String.fun();String str1 = new String("1234");String str2 = new String("12");String str3 = str1;System.out.println(str1.length());System.out.println(str3.isEmpty());}

str1的引用变量的地址赋值给了str3,此时的str3引用变量存储的是str1的地址,这样也可以通过str3引用变量来指向str1中的字符串的内容。
上述的打印结果分别是4,和false则可以证明这个结论。
在这里插入图片描述
结果显示,结论正确。
就接下来看看画图演示:
在这里插入图片描述
2. 在Java中“”引起来的也是String类型对象。

System.out.println(str1.length());System.out.println(str3.isEmpty());System.out.println("hello".length());

在这里插入图片描述

2.2 String对象的比较

字符串的比较是常见操作之一,比如:字符串排序。Java中总共提供了4中方式:

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

对于简单类型""是比较数值的大小,而对于引用类型“”是比较引用变量的地址。

  public static void main(String[] args) {//简单类型int a = 10;int b = 10;//引用类型String str1 = new String("abcdefg");String str2 = new String("abcdefg");//比较简单类型System.out.println(a == b);//true  false//比较引用类型System.out.println(str1 == str2);}}

在这里插入图片描述

结果显示:在基本类型中比较的是数值,而在引用类型当中比较的是地址。
2. boolean equals(Object anObject) 方法:按照字典序比较:
比较返回类型为boolean类型,相同则返回true不相同则返回false
字典序:字符大小的顺序,字符大小:字符返回的ASCII值。
String类重写了父类Object中equals方法,Object中equals默认按照==比较:

 public boolean equals(Object obj) {return (this == obj);}

因为object中equals默认按照==比较,所以我们要在String类中重写equals方法:

//在String中重写的equals方法:
public boolean equals(Object anObject) {if (this == anObject) {return true;}if (anObject instanceof String) {String anotherString = (String)anObject;int n = value.length;if (n == anotherString.value.length) {char v1[] = value;char v2[] = anotherString.value;int i = 0;while (n-- != 0) {if (v1[i] != v2[i])return false;i++;}return true;}}return false;}

接下来我们来通过str1.equals(str2)比较引用类型的内容:

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

在这里插入图片描述
通过重写equals方法,我们就可以用字典序来比较字符串的大小了。
在比较字符串的大小的时候:
第一步:我们通过字典序来比较。
第二步:当字典序相同的时候,我们可以通过字符串的长度来比较。
3. int compareTo(String s) 方法: 按照字典序进行比较:
这个和equals不同的是,返回类型不是boolean类型而是int类型,比较方式:

  1. 先按照字典次序大小比较,如果出现不等的字符,直接返回这两个字符的大小差值
  2. 如果前k个字符相等(k为两个字符长度最小值),返回值两个字符串长度差值
 public static void main(String[] args) {String str1 = new String("abcdefg");String str2 = new String("abcdefg");String str3 = new String("ABCDEFG");System.out.println(str1.compareTo(str2));System.out.println(str1.compareTo(str3));}

在这里插入图片描述
4. int compareToIgnoreCase(String str) 方法:与compareTo方式相同,但是忽略大小写比较:

public static void main(String[] args) {String str1 = new String("abcdefg");String str2 = new String("abcdefg");String str3 = new String("ABCDEFG");String str4 = new String("zhangsan");System.out.println(str1.compareToIgnoreCase(str2));System.out.println(str1.compareToIgnoreCase(str3));System.out.println(str1.compareToIgnoreCase(str4));}

在这里插入图片描述

2.3 字符串查找

字符串查找也是字符串中非常常见的操作,String类提供的常用查找的方法:

  1. public char charAt(int index)从字符串中拿到一个字符。

在String类中的方法是这么实现的。
在这里插入图片描述
自己来实现一下这个方法:

public static void main(String[] args) {String str1 = new String("abcdef");char ch = str1.charAt(0);//'a'char ch1 = str1.charAt(1);//'b'char ch2 = str1.charAt(-1);//抛异常char ch3 = str1.charAt(6);//抛异常System.out.println(ch);System.out.println(ch1);System.out.println(ch2);System.out.println(ch3);}
  1. int indexOf(int ch) 返回字符的下标,找不到就返回-1,从头开始一个一个找。
    我们来实现一下这个方法:
public static void main(String[] args) {String str1 = new String("abcdef");System.out.println(str1.indexOf('a'));System.out.println(str1.indexOf('b'));System.out.println(str1.indexOf('z'));}

在这里插入图片描述
3. int indexOf(int ch, intfromIndex) 从指定位置开始找这个字符,找到返回下标,找不到就返回-1。
我们来实现这个方法:

 public static void main(String[] args) {String str = new String("hello");System.out.println(str.indexOf('l', 3));}

在这里插入图片描述
4. int indexOf(String str) 从头开始在字符串A找字符串B,找到了返回字符串A中字符串B的第一个下标,比如:字符串A"hello",字符串B"llo"则返回"llo"在字符串A的下标,找不到就返回-1.
我们来实现这个方法:|

 public static void main(String[] args) {String str = new String("hello");System.out.println(str.indexOf("llo"));System.out.println(str.indexOf("all"));}

在这里插入图片描述
5 . int indexOf(String str, intfromIndex) 在指定位置从字符串A中找字符串B,找到还是一样返回字符串A中字符串B的第一个下标。找不到返回-1.
我们来实现这个方法:

public static void main(String[] args) {String str = new String("hello");System.out.println(str.indexOf("llo", 2));System.out.println(str.indexOf("llo", 4));}

在这里插入图片描述
6. int lastIndexOf(int ch) 从字符串最后的位置找目标字符,找到就返回其下标,找不到就返回-1.
我们来实现这个方法:

 public static void main(String[] args) {String str = new String("hello");System.out.println(str.lastIndexOf('o'));System.out.println(str.lastIndexOf('a'));}

在这里插入图片描述
**【注意】**这个找到的下标还是从前往后数的下标,而不是从后往前数的。
7. int lastIndexOf(int ch, intfromIndex) 这个是从指定位置,往后找这个字符,找到返回其下标,找不到就返回-1.
我们来实现这个方法:

 public static void main(String[] args) {String str = new String("hello");System.out.println(str.lastIndexOf('l', 4));System.out.println(str.lastIndexOf('l', 1));

在这里插入图片描述
8. int lastIndexOf(String str) 从后往前在字符串A中找字符串B,找到了返回字符串A中字符串B的第一个下标,找不到就返回-1.
我们来实现这个方法:

 public static void main(String[] args) {String str = new String("hello");System.out.println(str.lastIndexOf("llo"));System.out.println(str.lastIndexOf("lle"));

在这里插入图片描述
9. int lastIndexOf(String str, intfromIndex) 从指定位置从后往前在字符串A中找字符串B,找到了返回字符串A中字符串B的第一个下标,找不到就返回-1.
我们来实现这个方法:

  public static void main(String[] args) {String str = new String("hello");System.out.println(str.lastIndexOf("llo", 4));System.out.println(str.lastIndexOf("llo", 1));

在这里插入图片描述

2.4 转化

1. 数值和字符串转化

public static void main(String[] args) {//数字转字符串String str = String.valueOf(123);System.out.println(str);//字符串转数字Integer ii = Integer.valueOf("123");System.out.println(ii);}

字符串转化其他类型,构成了一个重载方法:String.valueOf()
在这里插入图片描述
其他类型转化String类型:
Integer.valueOf()
Float.valueOF()

2. 大小写转换

public static void main(String[] args) {String str = new String("abc");String str1 = new String("ABC");//小写转化为大写System.out.println(str.toUpperCase());//大写转化小写System.out.println(str1.toLowerCase());}

在这里插入图片描述
3. 字符串转数组
字符串转化数组
toCharArray()

 public static void main(String[] args) {String str ="abc";char[] chars = str.toCharArray();System.out.println(Arrays.toString(chars));}

在这里插入图片描述
数组转化为字符串

 public static void main(String[] args) {char[] chars = {'1','2','3'};String str = new String(chars);System.out.println(str);}

4.格式化
String.format()

public static void main(String[] args) {String s = String.format("%d-%d-%d", 2019, 9,14);System.out.println(s);}

2.5 字符串替换

使用一个指定的新的字符串替换掉已有的字符串数据,可用的方法如下:
1.String replaceAll(String regex, String replacement) 替换所有指定的内容
String regex:被替换的内容
String replacement:替换的内容

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

2.String replaceFirst(String regex, String replacement) 替换首个内容
String regex:在被替换的内容中出现第一次的内容
String replacement:替换的内容

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

在这里插入图片描述
注意事项: 由于字符串是不可变对象, 替换不修改当前字符串, 而是产生一个新的字符串.

2.6 字符串拆分

可以将一个完整的字符串按照指定的分隔符划分为若干个子字符串。
可用方法如下:
1.String[] split(String regex) 将字符串全部拆分,将字符串拆分,用字符串数组来接收。
String regex:以指定的格式拆分

public static void main(String[] args) {String str = "hello world java SE";String[] ret = str.split(" ");for (String s:ret) {System.out.println(s);}}

2.String[] split(String regex, int limit) 将字符串以指定的格式,拆分为limit组
String regex:以指定的格式拆分
int limit:拆分几组

public static void main(String[] args) {String str = "hello world java SE";String[] ret = str.split(" "2);for (String s:ret) {System.out.println(s);}}

注意事项:

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

2.7 字符串截取

从一个完整的字符串之中截取出部分内容。可用方法如下:
1.String substring(int beginIndex) 从指定位置截取到结尾
int beginIndex:指定位置

String str = "helloworld" ;
System.out.println(str.substring(5));

2.String substring(int beginIndex, int endIndex) 截取部分内容
int beginIndex:截取的开始位置
int endIndex: 截取的结束位置

String str = "helloworld" ;
System.out.println(str.substring(0, 5));

注意事项:

  1. 索引从0开始
  2. 注意前闭后开区间的写法, substring(0, 5) 表示包含 0 号下标的字符, 不包含 5 号下标

2.8 字符串的不可变性

String是一种不可变对象. 字符串中的内容是不可改变。字符串不可被修改,是因为:
1. String类在设计时就是不可改变的,String类实现描述中已经说明了:
在这里插入图片描述
在这里插入图片描述
String类中的字符实际保存在内部维护的value字符数组中,该图还可以看出:

  1. String类被final修饰,表明该类不能被继承
  2. value被修饰被final修饰,只能引用当前初始化好的对象不能引用其他对象,但是其引用空间中的内容可以修改。
    2. 所有涉及到可能修改字符串内容的操作都是创建一个新对象,改变的是新对象

最后总结一下:字符串不可变是因为其内部保存字符的数组被final修饰了,因此不能改变。这种说法是错误的。
字符串不可变的原因有两点:
1.String类被final修饰,表明该类不能被继承
2.value被修饰被final修饰,只能引用当前初始化好的对象不能引用其他对象,但是其引用空间中的内容可以修改

2.11 字符串修改

注意:尽量避免直接对String类型对象进行修改,因为String类是不能修改的,所有的修改都会创建新对象,效率非常低下。
我们通过拼接符“+”确实可以对字符串进行修改,但是这样的效率太慢了。

public static void main(String[] args) {
String s = "hello";
s += " world";
System.out.println(s); // 输出:hello world
}

但是这种方式不推荐使用,因为其效率非常低,中间创建了好多临时对象。
关于这些临时变量怎么可以看到,我们可以通过反汇编的方式可以看到:
在这里插入图片描述
在这里插入图片描述
根据上面的图片我们可以看到有两个新的类:StringBuilder和StringBuffer
在这两个类中字符串是可以改变的。
接下来我们来看看这两个类把!

3.StringBuilder和StringBuffer

3.1 StringBuilder的介绍

由于String的不可更改特性,为了方便字符串的修改,Java中又提供StringBuilder和StringBuffer类。这两个类大部分功能是相同的,这里介绍 StringBuilder常用的一些方法:
在这里插入图片描述
在这里插入图片描述
从上述方法可以看出:String和StringBuilder最大的区别在于String的内容无法修改,而StringBuilder的内容可以修改。频繁修改字符串的情况考虑使用StringBuilder。
这些方法我就不一一解释了,和上述String类方法差不多。
结尾:
希望大家可以给我点点关注,点点赞,你们的支持就是我的最大鼓励。🌹🌹🌹🌹🌹🌹🌹🌹🌹🌹🌹🌹🌹🌹

这篇关于【Java SE】带你在String类世界中遨游!!!的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/434891

相关文章

Spring三级缓存解决循环依赖的解析过程

《Spring三级缓存解决循环依赖的解析过程》:本文主要介绍Spring三级缓存解决循环依赖的解析过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、循环依赖场景二、三级缓存定义三、解决流程(以ServiceA和ServiceB为例)四、关键机制详解五、设计约

spring IOC的理解之原理和实现过程

《springIOC的理解之原理和实现过程》:本文主要介绍springIOC的理解之原理和实现过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、IoC 核心概念二、核心原理1. 容器架构2. 核心组件3. 工作流程三、关键实现机制1. Bean生命周期2.

解决tomcat启动时报Junit相关错误java.lang.ClassNotFoundException: org.junit.Test问题

《解决tomcat启动时报Junit相关错误java.lang.ClassNotFoundException:org.junit.Test问题》:本文主要介绍解决tomcat启动时报Junit相... 目录tomcat启动时报Junit相关错误Java.lang.ClassNotFoundException

Gradle下如何搭建SpringCloud分布式环境

《Gradle下如何搭建SpringCloud分布式环境》:本文主要介绍Gradle下如何搭建SpringCloud分布式环境问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录Gradle下搭建SpringCloud分布式环境1.idea配置好gradle2.创建一个空的gr

JVM垃圾回收机制之GC解读

《JVM垃圾回收机制之GC解读》:本文主要介绍JVM垃圾回收机制之GC,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、死亡对象的判断算法1.1 引用计数算法1.2 可达性分析算法二、垃圾回收算法2.1 标记-清除算法2.2 复制算法2.3 标记-整理算法2.4

springboot集成Lucene的详细指南

《springboot集成Lucene的详细指南》这篇文章主要为大家详细介绍了springboot集成Lucene的详细指南,文中的示例代码讲解详细,具有一定的借鉴价值,感兴趣的小伙伴可以跟随小编一起... 目录添加依赖创建配置类创建实体类创建索引服务类创建搜索服务类创建控制器类使用示例以下是 Spring

Java调用Python的四种方法小结

《Java调用Python的四种方法小结》在现代开发中,结合不同编程语言的优势往往能达到事半功倍的效果,本文将详细介绍四种在Java中调用Python的方法,并推荐一种最常用且实用的方法,希望对大家有... 目录一、在Java类中直接执行python语句二、在Java中直接调用Python脚本三、使用Run

Java根据IP地址实现归属地获取

《Java根据IP地址实现归属地获取》Ip2region是一个离线IP地址定位库和IP定位数据管理框架,这篇文章主要为大家详细介绍了Java如何使用Ip2region实现根据IP地址获取归属地,感兴趣... 目录一、使用Ip2region离线获取1、Ip2region简介2、导包3、下编程载xdb文件4、J

浅析如何使用xstream实现javaBean与xml互转

《浅析如何使用xstream实现javaBean与xml互转》XStream是一个用于将Java对象与XML之间进行转换的库,它非常简单易用,下面将详细介绍如何使用XStream实现JavaBean与... 目录1. 引入依赖2. 定义 JavaBean3. JavaBean 转 XML4. XML 转 J

SpringBoot中四种AOP实战应用场景及代码实现

《SpringBoot中四种AOP实战应用场景及代码实现》面向切面编程(AOP)是Spring框架的核心功能之一,它通过预编译和运行期动态代理实现程序功能的统一维护,在SpringBoot应用中,AO... 目录引言场景一:日志记录与性能监控业务需求实现方案使用示例扩展:MDC实现请求跟踪场景二:权限控制与