3:String类

String类

https://blog.csdn.net/TYRA9/article/details/129348766

1:介绍:

每一个字符串对象都是常量。字符串中的字符使用unicode编码,一个字符(不区分中英文)均占两个字节。java中用String类描述字符串,如下图所示 :

在这里插入图片描述

String类用final关键字修饰,因此String类是不可被其他类继承的;并且,通过String类中的属性value,我们可以得知String类的底层实际其实是字符数组char[ ] 。也就是说,new出的String对象在堆空间中,该对象的空间里有value引用变量指向常量池中一数组,用于存放字符串的内容(实际是指向常量池的地址)。该value数组也使用了final关键字修饰当final关键字修饰引用类型时,不可更改其引用的指向,即不能更改其保存的地址值。

2:String类实现了很多的接口:

其中最重要的是以下两个

*Serializable接口*,实现该接口使得String类型可串行化,串行化后,String类型可以进行网络传输。

*Comparable接口*,实现该接口使得String类型可以进行“比较”的操作。

3;String类常用构造器

// 1.String():该构造器可以初始化一个String对象,使其指向一个空字符序列。
String str1 = new String();
System.out.println(str1); // 
// 2.String(byte[] bytes):该构造器可以初始化一个String对象,并将指定字节数组中的数据转化成字符串。
byte[] bytes = {65, 66, 67, 68};
String str2 = new String(bytes);
System.out.println(str2); // ABCD
// 3.String(char[] value):该构造器可以初始化一个String对象,并将指定字符数组中的数据转化成字符串。
char[] value = {'C', 'y', 'a', 'n', '_', 'R', 'A', '9'};
String str3 = new String(value);
System.out.println(str3); // Cyan_RA9
// 4.String(char[] value, int offset, int count):该构造器可以初始化一个String对象,并将指定字符数组中的指定数据		转化成字符串。 
String str4 = new String(value, 0, 4);
System.out.println(str4); // Cyan
//  5.String(String original):该构造器可以初始化一个String对象,使该对象实际指向的字符串常量与传入的字符串形参相		同,相当于是形参的一份拷贝。
String str5 = new String("CSDN yyds!");
System.out.println(str5); // CSDN yyds!

4:不同方式创建String类对象的区别

(1)直接赋值的方式

String str_0 = "Cyan"

String类在实际开发中的使用场景非常多,java在底层提供了针对String类的优化,即可以不通过构造器来创建String对象。而是直接赋值一个字符串。
String str_0 = “Cyan”; ,使用这种方式来创建String对象,jvm会先从常量池中查看是否有"Cyan"字符串的数据空间,若有,令引用变量直接指向该空间;若无,重新创建"Cyan"的数据空间并令其引用变量指向它。因此,str_0引用最终直接指向的是常量池中"Cyan"常量的空间地址。

在这里插入图片描述

在这里插入图片描述

(2)常规new的方式

String str_1 = new String("Cyan"); 

使用这种方式来创建String对象,jvm会先在堆空间中给String对象开辟空间,这片空间中维护了value数组这一属性,该属性指向常量池的"Cyan"数据空间。若常量池中没有"Cyan",则重写创建"Cyan"数据空间,并让value引用指向该数据空间最后,将该对象堆空间的地址值返回给str_1引用。因此,str_1引用最终直接指向的是堆中的空间地址。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

(3)字符串拼接形式

String str_0 = "Cyan" + "RA9"; 

若使用字符串拼接的方式来创建字符串对象,如下 :
当我们以两个字符串拼接的形式来创建字符串对象时,**jvm不会在常量池中分别创建"Cyan"字符串常量和"RA9"字符串常量,再把它们拼接起来。而是直接在底层优化,先把两个字符串拼接起来,**之后直接去常量池中寻找有没有拼接起来的这个字符串常量,如果有,直接令该引用指向这个字符串常量的空间地址;如果没有则先创建该字符串常量,再让引用指向这里

(4)有变量参与的字符串拼接

String a = "abc";
String b = a + "def"; // 创建一个StringBuilder对象,然后对"abc"进行拼接,再对"def"进行拼接,最后将       					   StringBuilder调用toString转换成String类型赋给b.
System.out.println(b);

a变量在编译的时候不知道a是“abc”字符串,所以不会进行编译期优化,不会直接合并为“abcdef”

在这里插入图片描述

5:String类常用的方法

(1):charAt( )

根据字符串的下标找字符

String z = new String("abcdef");
char y = z.charAt(1);
System.out.println(y);
// b

(2):equals( )

比较的是两个字符串里面的内容是否是一样的。会区分大小写

在这里插入图片描述

(3):重写的compareTo方法

在这里插入图片描述

会发现:只有两个字符串完全相等的时候才会返回0,返回是正还是负有点字典序的意思。

(4):substring

字符串的截取

String s = "abcdefghigklmnopqrst";
System.out.println(s.substring(5)); // [5 , s.length)
System.out.println(s.substring(3,8)); // [3 , 8)
// fghigklmnopqrst
// defgh

(5):concat

字符串的拼接

String s = "abcdefghigklmnopqrst";
System.out.println(s.concat("ppp"));
// abcdefghigklmnopqrstppp

(6):replace

字符串中的字符替换

String str = "abcdeabcdeabcdeabcde";
System.out.println(str.replace("a", "w")); // 把str中的a替换成w
// wbcdewbcdewbcdewbcde

(7):split

按照指定的字符串进行分裂为数组的形式

String str = "a-b-c-d-e-f-g-h-i-k";
String[] nub1 = str.split("-");
System.out.println(Arrays.toString(nub1)); // [a, b, c, d, e, f, g, h, i, k]
String str3 = "a c n u";
String[] nub2 = str3.split(" ");
System.out.println(Arrays.toString(nub2)); // [a, c, n, u]
String str4 = "abc cba mba obuuu";
String[] nub3 = str4.split("b");
System.out.println(Arrays.toString(nub3)); // [a, c c, a m, a o, uuu]

(8):toUpperCase

将字符串转化成大写

String str = "a-b-c-d-e-f-g-h-i-k";
System.out.println(str.toUpperCase());
// A-B-C-D-E-F-G-H-I-K

(9):toLowerCase

将字符串转成小写

(10):trim

去除字符串的首尾空格

String str3 = "    a c n u   ";
System.out.println(str3.trim());
//a c n u

(11):toString

将字符串以字符串的形式打印,返回值还是String类型

String str3 = "    a c n u   ";
System.out.println(str3.toString());
//    a c n u   

(12):valueOf

转换为String类型,注意这是static修饰的一个类方法

在这里插入图片描述

char[] arr = {98,99,100};
System.out.println(String.valueOf(arr));
// bcd

StringBuilder StringBuffer

https://blog.csdn.net/TYRA9/article/details/129368975

1:介绍

在String类中,我们提到,**每个字符串对象都是常量。**当我们创建一个字符串对象,并试图对其内容进行“增”,“删”,或者“改”的操作时,实际上原来的字符串对象已经丢弃了jvm会重新创建一个字符串对象,**并令其指向常量池中新的数据空间。**所以,如果多次进行这些“增删改”的操作,会导致大量副本字符串对象遗留在内存中,降低效率。那我们如何解决这个问题?这便要引出我们的StringBuffer类和StringBuilder类。

StringBuffer类,指可变字符序列,用于构造字符串对象。其内部使用自动扩容的数组来操作字符串数据

StringBuffer继承的父类是AbstractStringBuilder。其存储字符的数组是value数组,该数组无final修饰! 因此数组的引用是可以发生变化的。字符串存放的位置是在堆内存中。[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SlPtmEzQ-1685333184887)(D:/%E4%BD%A0%E5%A5%BDJava/1100.png)]

注意这里面的额count

2:构造器

当使用无参构造器进行构造时,默认开辟的数组的大小是16.

在这里插入图片描述

在这里插入图片描述

当使用有参构造器进行构造时,开辟的数组的大小是你传入的值。

在这里插入图片描述

在这里插入图片描述

当传入的是字符串的时候,会开辟一个数组大小为str.length+16的数组,然后将传进来的字符串的内容拼接在后面。

在这里插入图片描述

在这里插入图片描述

3:StringBuffer VS String类(重要)

(1):StringBuffer类与String类的比较 :

①String类保存的是 字符串常量,无法直接更改字符串本身的值。String类的每次更新实际上就是更改引用指向的地址,效率较低。

String str_0 = new String("CSDN yyds");
str_0 = new String("666");
str_0 = "Cyan";

在这里插入图片描述

②StringBuffer保存的是 字符串变量,可以直接更改字符串本身的值。因为字符串变量在堆内存中,StringBuffer的每次更新实际上可以直接更新字符串的内容,不用每次更新地址,效率较高。只有在某些特殊情况下,比如说该数组预存的空间不足,需要扩容时,才创建新的对象。

在这里插入图片描述

(2):StringBuffer类与String类的相互转化 :

①String ——> StringBuffer

// 方法一:
StringBuffer sb1 = new StringBuffer("CSDN yyds");
// 方法二:
StringBuffer sb2 = new StringBuffer();
sb2.append("csdn");

②StringBuffer ——> String

// 方法一:
StringBuffer sb1 = new StringBuffer("CSDN yyds");
String s1 = sb1.toString();
// 方法二:
StringBuffer sb2 = new StringBuffer("CSDN yyds");
String s2 = new String(sb2);

在这里插入图片描述

在这里插入图片描述

4:StringBuffer类常用方法

	   StringBuffer sb = new StringBuffer("abcdefghijklmnopqrstuvwxyz");
     // 增
     sb.append("很美");
     System.out.println(sb.toString()); // abcdefghijklmnopqrstuvwxyz很美
     // 删
     sb.delete(1,3); // [1,3)
     System.out.println(sb); // adefghijklmnopqrstuvwxyz很美

     sb.deleteCharAt(1); // 删除某个位置上的字符
     System.out.println(sb); // aefghijklmnopqrstuvwxyz很美
     // 改:插入
     sb.insert(3,"ABS"); // 在下标为3的位置插入ABS
     System.out.println(sb); // aefABSghijklmnopqrstuvwxyz很美
     // 改:替换
     sb.replace(3,5, "KKK"); // 将字符串的[3 , 5)位置用KKK替换
     System.out.println(sb); // aefKKKSghijklmnopqrstuvwxyz很美

     sb.setCharAt(0,'!'); // 在0下标的位置设置成!
     System.out.println(sb); // !efKKKSghijklmnopqrstuvwxyz很美
     // 字符串的反转
     sb.reverse();
     System.out.println(sb); // 美很zyxwvutsrqponmlkjihgSKKKfe!
     // 字符串的截取
     String str5 = sb.substring(3,7); // 注意返回的是String类型的
     System.out.println(str5); // yxwv

5:String类,StringBuffer类,StringBuilder类总比较

String : 不可变字符序列,效率低,但是复用率高。
StringBuffer : 可变字符序列,效率较高,且线程安全。
StringBuilder : 可变字符序列,效率最高,但线程不安全。

①String : 适用于字符串很少被修改,且被多个对象引用的情况,比如定义数据库的IP信息,配置信息等。
②StringBuffer : 适用于存在大量修改字符串的情况,且满足 多线程条件。
③StringBuilder : 适用于存在大量修改字符串的情况,且满足 单线程条件。

当然可以!以下是我给20岁的年轻人的一些建议:

  1. 保持好奇心:继续学习新知识,了解不同的文化、语言和经验。保持开放的思想和好奇心将有助于您发现自己的兴趣,并为未来的职业规划做出决策。
  2. 重视人际关系:建立真正的友谊和社交网络,这将成为你未来成功的关键。与人相处的艺术是一种非常重要的技能,尝试建立真正的联系,让自己的人际关系更加丰富。
  3. 培养健康的生活习惯:注意健康饮食,每天锻炼并且充足的睡眠。保持身体和心理的健康是成功和幸福的重要基础。
  4. 创造自己的未来:不要让其他人的期望或意见左右你的决策,相信自己的直觉并努力实现自己的梦想。尝试新事物,学习新技能,不断挑战自己并扩展自己的舒适区。
  5. 投资自己的未来:无论是通过进一步教育还是自学,投资于自己的知识和技能,可以帮助你实现更高的目标和薪资水平。考虑你未来职业的需求并选择适合的课程或实践经验,提高自己的竞争力。

希望这些建议对你有所帮助,祝你好运!

https://www.youtube.com/GeographyNow

https://www.youtube.com/smartereveryday

https://www.youtube.com/RuriOhama

https://www.youtube.com/Thomasfrank

https://www.youtube.com/RealLifeEnglish1

https://www.youtube.com/MattDAvella

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HackerTerry

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值