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

【字符串String类大集合】构造创建_常量池情况_获取方法_截取方法_转换方法_String和基本数据类型互转方法

目录

  • 字符串
    • 字符串的常用3+1种构造方法
  • 字符串的比较方法
    • 什么情况字符串内容相同就是同一个对象
    • 常量池问题讨论
    • 如何判断字符串是否是同一个对象(是否在常量池)
    • equals和==
  • 字符串的常用方法
    • 4个获取;长度;拼接;获取索引位置字符;获取字符串首次出现的索引
    • 2种截取方法(重载);左闭右尾;左闭右开
    • 字符串的3种转换相关方法;转char[];转byte[];批量替换指定字符串
    • 字符串的1种分割方法;删掉给定字符串并分割
  • ★以上所有常用方法使用
    • ❤参与拼接和截取,替换后String的常量池情况
  • ❤String与基本数据和数组的互相转换
    • 基本数据类型(4类8种)转String
    • String转基本数据类型
    • 数组转String
    • 易记

字符串

在java.lang包下,所以不用导包。
程序中所有的双引号字符串,都是String类的对象(就算没有new也是)

字符串的特点:
1.内容永不可变
2.因为字符串内容不可变,所以可以共享
3.字符串效果上相当于是char[]字符数组,但是底层原理是byte[]字节数组

字符串的常用3+1种构造方法

1public String();创建一个空白字符串, 不含有任何内容
2public String(char[] array);根据字符数组的内容,来创建对应的字符串
3public String(byte[] array);根据字节数组的内筒,来创建对应的字符串

1种直接创建
String str = "Hello";注意:直接写上双引号,就是字符串对象。只要是字符串一定是对象
注意

字符串的比较方法

public boolean equalsIgnoreCase(String str);//忽略大小写进行内容比较

什么情况字符串内容相同就是同一个对象

当字符串在常量池中时,内容相同就是同一个对象

常量池问题讨论

字面量:即’‘或""括起的部分字符或字符串。例如’a’、‘b’ 或 '\n’为字符字面量。"Hello,World"为字符串字面量,一旦创建不可更改
1)字符串在常量池的2种情况

  • 字符串字面量(即双直接用引号创建的字符串),就在字符串常量池中。
    即直接创建的字符串在常量池,若内容相同即为共享一个对象,即""通过双引号直接创建的字符串都在常量池,内容相同的情况其实是使用的常量池中的同一个对象,所以比较结果为true
    当使用双引号直接定义字符串时(如 String s = "abc";),JVM 会先检查常量池:
    ①若常量池中已存在 “abc”,则直接将引用指向该对象;
    ②若不存在,则在常量池中创建 “abc” 并指向它。
    ③这种情况下,字符串必然存在于常量池中。
  • 如果有截取或拼接的操作
    核心判断依据是操作是否在编译期可确定,还是运行期动态生成:
    只有参与拼接的字符串全为 字符串字面量并使用+拼接后的字符串才在常量池
    若字符串是通过编译期可确定的常量表达式生成的(如字面量拼接),其结果会被编译器直接计算并放入常量池。
    编译期可确定的使用+拼接(常量表达式):结果在常量池。
    注意:只有当拼接的所有部分都是字面量或 final 变量时,结果才会在编译期合并并放入常量池。
    例如:
运行
String s1 = "a" + "b" + "c"; // 编译期直接合并为 "abc",存在于常量池
String s1 = "a";//字符串字面量,直接赋值创建的所以在常量池
String s2 = "b";//同上
String s3 = "a" + s2; // 编译期无法确定(s2 是变量),结果在堆中
String s4 = "a" + "b"; // 编译期确定为 "ab",在常量池
String s5 = "a".concat("b");// 编译期确定为 "ab",在常量池, ●注意!只是内容恰巧相同而非一个对象

concat后在常量池只有一种特殊情况:concat() 的操作结果是编译期可确定的常量表达式,且结果已存在于常量池。也只是内容相同,而非同一个对象
唯一的例外是:如果 concat() 的结果与常量池中的某个字面量完全相同,且该字面量在拼接前已存在于常量池(例如 (“a”.concat(“b”)) 与常量池中的 “ab” 相同),此时两者的值相等,但 concat() 返回的对象本身仍在堆中,只是与常量池中的对象内容一致。
总结:concat() 始终是运行期操作,结果默认在堆中;只有编译期的 + 运算符拼接常量时,结果才会直接进入常量池。 其他操作字符串的方法同理

  • 对于其他的操作方法,都不会在常量池
    例如:new String("a") + new String("b") 的结果是堆中的新对象,需调用 intern() 才会进入常量池。(暂不提)
    substring 方法的结果默认在堆中,无论原始字符串是否在常量池。
    replace、replaceAll 等替换操作的结果默认在堆中,即使原始字符串在常量池

2) 字符串不在常量池的情况

构造方法创建的字符串都不在常量池,存在堆中,内容相同也不是同一个对象
哪怕构造器使用同一个数组,创建的内容也完全相同,也是不同的对象

除非是改引用名,本质是同一个对象,即多个引用名指向同一个对象
例如:
char[] charArray = {'a', 'b', 'c'};
String str3 = new String(charArray);
String str4 = str3; 这种情况,给这个对象加了一个引用名
System.out.println(str3 == str4);就是true。相当于同一个对象有两个引用名而已

哪怕用同样的数组构造字符串,只要用来构造方法就是独立的两个对象,如下
String str5 = new String(charArray);
System.out.println(str3 == str4);//true。
System.out.println(str3 == str5);//false

如何判断字符串是否是同一个对象(是否在常量池)

equals和==

== 比较
① 对于基本数据类型比较 内容
② 对于引用类,只有是同一个对象才是true(比较的是对象的内存地址)
equals
只能比较引用对象
① 对于普通类对象,只有同为同一个对象才是true
② 但对于File,String,Data和包装类,是比较内容(因为他们自己重写了tostring方法)

public class Demo2ConstantPools {public static void main(String[] args) {String str1 = "abc";String str2 = "abc";char[] charArray = {'a', 'b', 'c'};String str3 = new String(charArray);byte[] byteArray = { 'a', 'b', 'c'};String str4 = new String(byteArray);String str5 = new String(byteArray);System.out.println(str1 == str2);//true 验证,字面量在常量池是同一个对象System.out.println(str2 == str3);//falseSystem.out.println(str3 == str4);//falseSystem.out.println(str4 == str5);//false 同一个数组做参数,但只要是构造器创建的就不在常量池,在堆,↑str3,4,5都是是独立的两个对象,哪怕内容相同System.out.println(str1.equals(str2));//trueSystem.out.println(str2.equals(str3));//trueSystem.out.println(str3.equals(str4));//trueSystem.out.println(str4.equals(str5));//true ↑因为内容相同System.out.println(str1.equalsIgnoreCase("ABC"));//true}
}

字符串的常用方法

4个获取;长度;拼接;获取索引位置字符;获取字符串首次出现的索引

统一为 String str ; str.方法名来调用
public int length(); 获取字符个数,即字符串长度
public String concat(String str); 将当前字符串和参数拼接返回
public char charAt(int index); 获取指定索引位置的单个字符(第一个字符的索引为0,从0开始)
public int indexOf(String str); 查出参数字符串在本字符串中首次出现的索引位置,没有就return -1

注意:concat方法只会把拼接的结果返回,并不改变调用方法的字符串。除非原字符串接收他的返回值

2种截取方法(重载);左闭右尾;左闭右开

public String substring(int index);截取从参数位置一直到字符串末尾。返回新字符串
public String substring(int begin, int end);截取从begin开始一直到end结束中间的字符串。(按照索引从0开始对应 每一个字符,截取为 [begin,end)左闭右开)

字符串的3种转换相关方法;转char[];转byte[];批量替换指定字符串

public char[] toCharArray();将当前字符串拆分为字符数组作为返回值
public byte[] getBytes();获得当前字符串底层的字节数组
public String replace(CharSequence oldString, CharSequence newString); 将所有出现的老字符替换成为新的字符串,返回替换后的新字符串(CharSequence简单理解为可以接收String类型)

字符串的1种分割方法;删掉给定字符串并分割

public String[] split(String regex);按照参数的规则将字符串切分成为若干部分

特殊情况: 无法根据.划分做参数,split方法的参数其实是一个正则表达式,如果按照英文句“.”必须写“\.”
注意: . 、 $、 | 和 * 等转义字符,必须得加 \。

split() 方法根据匹配给定的正则表达式来拆分字符串。

★以上所有常用方法使用

public class Demo3StringMethod {public static void main(String[] args) {//字符串的4个获取方法String str1 = "Hi~Barbie";System.out.println(str1.length());//9System.out.println(str1.concat("Hi~Ken"));//Hi~BarbieHi~KenSystem.out.println("索引3的字符" + str1.charAt(3));//Bstr1 = str1.concat("bie~hello java $ rusty lake is fate 1 larua is blossom");System.out.println("str1 : " + str1);//Hi~BarbieHi~Kenbie~hello java $ rusty lake is fate 1 larua is blossomSystem.out.println("第一次出现bie的索引位置:" + str1.indexOf("bie"));//6//字符串的截取方法System.out.println("从4截取" + str1.substring(12));//~Kenbie~hello java $ rusty lake is fate 1 larua is blossomSystem.out.println("从[7,13)截取" + str1.substring(17,27));//e~hello ja//字符串的转换相关方法char[] ch = str1.toCharArray();System.out.println("char数组:" + ch);System.out.println(Arrays.toString(ch));byte[] by = str1.getBytes();System.out.println("by数组:" + by + Arrays.toString(by));for (int i = 0; i < by.length; i++) {System.out.print(by[i] + ",");}System.out.println();String str2 = "Hoow doo yoou doo?";System.out.println("str2" + str2);System.out.println(str2.replace("oo", "*"));//字符串的分割方法String[] str3 = str1.split("a");System.out.println("根据a划分str1:"+ str1);for (int i = 0; i < str3.length; i++) {System.out.println(str3[i]);}String str3 = "ewr.e..wfs...as.a.d";String[] atr = str3.split("\\.");printArray(atr);String str4 = "ewr\ne.\nwfs.n.as.d";String[] atr2 = str4.split("\\n");printArray(atr2);}
}

❤参与拼接和截取,替换后String的常量池情况

总结: +拼接,并且拼接涉及的所有字符串全为字面量形式。只有这一种操作方式后的字符串在常量池。其他都不在

	private static void demo02(){String s1 = "Barbie";String s2 = "Barbie";System.out.println(s1 == s2);//true只有这种创建方式字符串在常量池//拼接: + concat//截取:substring,替换replace,replaceAll//❤唯1操作后还在常量池的❤String s3 = "Ba"+"rbie";System.out.println(s2+"=="+s3 +":" + (s2 == s3));//true
//        String s3 = "ab1c" + "es";
//        String s4 = "ab1c".concat("es");//除了所有操作值都是字面量以外,操作结果已经存在在常量池
//        System.out.println(s3 + "==" + s4 + ":" + (s3 == s4));//false,/* s4的操作结果"ab1ces"事先并不在常量池,s3虽然在常量池,但编译期还没有操作完成* 就算在==也是false,因为最多内容相同,不可能是同一个对象。concat操作后的值始终在堆*/String s4 = "!@#4".concat("1234");//结果事先并不存在,也不在常量池。String s44 = "!@" + "#41234";System.out.println(s4 + "==" + s44 + ":" + (s4 == s44));//falseSystem.out.println(s4 + ".equals" + s44 + ":" + (s4.equals(s44)));//true//其他方法 ● substring,replace返回的String都是默认在堆中String s5 = "32145Barbie".substring(5);String s6 = "231Barbie31".substring(3,9);System.out.println(s5 + " == " + s6 + ":" + (s5 == s6));//falseSystem.out.println(s5 + ".equals(" + s6 + ":" + (s5.equals(s6)));//trueString s7 = "123123".replace("12", "Barbie");String s8 = "Barbie3Barbie3";System.out.println(s7+"=="+s8+ ":" + (s7 == s8));//falseSystem.out.println(s7+".equals("+s8+ ":" + (s7.equals(s8)));//trueString s9 = "123123".replaceAll("12", "Barbie");String s10 = "Barbie3Barbie3";System.out.println(s7+"=="+s8+ ":" + (s9 == s10));//falseSystem.out.println(s7+".equals("+s8+ ":" + (s9.equals(s10)));//true}

❤String与基本数据和数组的互相转换

基本数据类型(4类8种)转String

  1. 变量+ "" -->原理:输出时,+字符串之后都默认为字符串,并且拼接

  2. 包装类名.toString(该包装类对应的基本数据类型); 如Integer.toString(i),Double.toString(d)

  3. String.valueOf(基本数据类型); 把基本数据类型转为String类型

		String bs1 = b +"";String ss1 = s + "";String is2 = Integer.toString(i);String ls2 = Long.toString(l);String ds3 = String.valueOf(d);String fs3 = String.valueOf(f);

String转基本数据类型

  1. int num = Integer.parseInt(str);//直接解析为int类型的变量
    char:无直接的 parseChar 方法,需通过以下方式:
    若字符串长度为 1,取其首个字符:char c = str.charAt(0);
    若字符串是 Unicode 编码(如 “\u0061”),可先解析为 int 再强转:char c = (char) Integer.parseInt(“0061”, 16);

  2. int num = Integer.valueOf(str).intValue();//用String做参数装箱后拆箱
    //包装类.valueOf(str)装箱,后intValue()拆箱
    Integer numInt = Integer.valueOf(str);//是包装类

  3. int num = new Integer(str).intValue();//装箱后拆箱

在这里插入代码片

数组转String

  1. new String([]) 打印字符串;仅支持char[]和byte[]数组
  2. Arrays.toString([]) ;有格式[元素1,元素2,……]
    3.返回参数的String形式String.valueOf(数组名); 仅支持变量和char数组
    Java可用打印数组方法5中+常用变量转字符串方法

易记

类名.toString(基本数据)的类一般为包装类
作用:把基本数据转为String,包装类名和基本数据类型对应
类名.valueOf(参数) 把参数包装到指定类名的类型
作用:装箱,参数可以是基本数据类型和String类型。
类名可以是String和8种包装类,可以把基本类型转String,也可以把String转包装类

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

相关文章:

  • Http请求中Accept的类型详细解析以及应用场景
  • 升鲜宝 供应链SCM 一体化自动化部署体系说明
  • grafana配置redis数据源预警误报问题(database is locked)
  • 拒绝繁琐,介绍一款简洁易用的项目管理工具-Kanass
  • 测试自动化新突破:金仓KReplay助力金融核心系统迁移周期缩减三周
  • 大语言模型入门指南:从科普到实战的技术笔记(1)
  • 大模型原理之Transformer进化历程与变种
  • 2025-简单点-ultralytics之LetterBox
  • 网站开发经济可行性分析石龙做网站
  • wordpress中国优化网络优化的目的
  • 【Linux网络】Socket编程TCP-实现Echo Server(下)
  • 路由协议的基础
  • ios 26的tabbar 背景透明
  • Hadoop大数据平台在中国AI时代的后续发展趋势研究CMP(类Cloudera CDP 7.3 404版华为鲲鹏Kunpeng)
  • Apache Jena:利用 SPARQL 查询与推理机深度挖掘知识图谱
  • Regression vs. Classification|回归vs分类
  • Nine.fun × AIOT重磅联手,打造健康娱乐新经济
  • The Life of a Read/Write Query for Apache Iceberg Tables
  • 网站显示图片标记html5做网站的代码
  • 做网站需要买多大空间哪里有好的免费的网站建设
  • gpt‑image‑1 —— OpenAI 全新图像生成模型全面解析
  • 基于scala使用flink将读取到的数据写入到kafka
  • 跨平台OPC UA开发:.NET、Java与C++ SDK的深度对比
  • 硬盘第一关:MBR VS GPT
  • 从原理到演进:vLLM PD分离KV cache传递机制全解析
  • 如何在浏览器侧边栏中使用GPT/Gemini/Claude进行网页对话?
  • 【gpt-oss-20b】一次 20B 大模型的私有化部署评测
  • zynq的PS端ENET网口引出到EMIO的PL引脚
  • 商城网站设计策划wordpress 去除归档链接
  • 李宏毅机器学习笔记44