当前位置:   article > 正文

Java --- 字符串(就这一篇带你学习字符串的绝大多数内容)

Java --- 字符串(就这一篇带你学习字符串的绝大多数内容)

引言:本期内容一系列参考B站黑马课程以及Java入门到进阶,如有细节问题还请见谅 

目录

一.数据类型

1.基本数据类型:

2.引用数据类型:

二.String类

1.创建字符串:

2.连接字符串:

3.存储原理:

4.==与equals():

5.常用的String类内的方法:

(1)截取字符串:对象.substring(int index)

 (2)获取单个字符:对象.charAt(int index)

(3)按照字典序比较大小:对象1.compareTo(对象2) 

 三.StringBuilder类

1.构造方法:

2.类内方法:

3.链式编程:

4.源码分析:

四.StringJoiner类

1.构造方法:

2.类内方法:


上期内容将Java类的对象相关内容介绍完成,那么本期讲给大家带来Java字符串内容详解。

一.数据类型

数据类型一般分为基本数据类型以及引用数据类型

1.基本数据类型

数据值存储在自己的空间中,可以赋值给其他对象。eg:int,double等

2.引用数据类型:

数据值存储在其它空间中,而自己空间存储的是地址值。eg:String等就像自己定义的类实际上也是属于引用数据类型。

二.String类

首先,字符串是Java程序经常处理的对象,而字符串会作为String类进行处理,而String类是Java定义好的一个类,定义在java.lang包中,以至于其不需要导包。

1.创建字符串:

咱们在创建字符串通常方式是:

String s1 = new String("hello world");

将字符串作为对象来处理,也就是类似创建类的对象一样创建字符串的对象。

同样,其实我们也是可以直接赋值的方式获取字符串的对象:

String s2 = "hello world";

也可以创建一个字符类型地数组,根据其内容创建字符串对象:

  1. char[] s = {'h','e','l','l','o',' ','w','o','r','l','d'};
  2. String s3 = new String(s);

2.连接字符串:

如果我们想要实现两个字符串的拼接,这其实仅需用"+"运算符就可以办到:

  1. String s1 = "hello";
  2. String s2 = "world";
  3. String s3 = s1 + ' ' + s2;
  4. System.out.println(s3);//hello world

如果将字符串同其他的数据类型数据进行连接,则会将其他数据类型地数据直接转换成字符串。

注意:

  1. int a = 1,b = 4,c = 5;
  2. System.out.println("a = " + a + " b = " + b + c + "是c的值");
  3. //a = 1 b = 45是c的值
  4. System.out.println("a = " + a + " b = " + (b + c) + "是c的值");
  5. //a = 1 b = 9是c的值

 括号的优先级比加号优先级高,以至于下面的代码会先执行(b + c)。

3.存储原理:

由于String是引用数据类型,所以其存储会与基本数据类型有所区别。

如果是下面的情况:

String s1 = "abc";

那么,JVM会先检查该字符串"abc"在串池是否存在,如果不存在就会创建新的,如果存在,则会复用这个字符串,而不会在串池重新创建新的字符串。(StringTable(串池)在堆内存中)

String s2 = new String("abc");

而如果使用new,就会在堆内存开辟空间创建String类,并通过s2记录对象地址值。

4.==与equals():

如果我们想要比较两个基本数据类型的变量的值,我们可以这样写:

  1. int a = 3,b = 4;
  2. bool flag = false;
  3. if(a == b)
  4. flag = true;
  5. System.out.println(flag);//false

而如果我们要比较两个引用数据类型呢?

  1. String s1 = "hello";
  2. String s2 = "hello";
  3. System.out.println(s1 == s2);//true
  4. String s3 = new String("hello");
  5. String s4 = new String("hello");
  6. System.out.println(s3 == s4);//false

嘶,为何s1 == s2可以是true呢?

这是因为上面提到的字符串存储问题,s1与s2的值都存储在串池中且s1与s2指向的是同一个"hello"。以至于会导致地址值相等,所以肯定返回true啊。

而s3 == s4是false呢?

这就需要我们回顾一下s3与s4存储的是什么了,因为利用new关键字在堆内存开辟新的两个空间,s3与s4分别对应其两个新构造出来的对象在堆内存的地址值,那两个地址值肯定是不一样的啊,所以肯定会false啊。

那么如何比较两个引用数据类型的大小呢?

这就需要Java给咱们提供的equals()方法

  1. public class Csdn1 {
  2. public static void main(String[] args) {
  3. String s3 = new String("hello");
  4. String s4 = new String("hello");
  5. System.out.println(s3.equals(s4));//true
  6. }
  7. }

下面通过表格的形式清晰观察这两个的区别:

==:对于两个基本数据类型的变量比较的是数据值,而对于两个引用数据类型比较的是地址值

equals():用这种方法比较两个用String类定义的对象,如果两个字符串具有相同的字符与长度,那么就会返回true。

5.equals()重写: 

如果想比较两个类的值,就需要将equals()方法重写,也就是将该方法从Object类中继承并覆盖。

这里我定义一个People类和一个继承People类的Student类:

  1. public class People {
  2. private int id;
  3. private String name;
  4. public People(int id, String name) {
  5. this.id = id;
  6. this.name = name;
  7. }
  8. }
  1. public class Student extends People{
  2. private double score;
  3. public Student(int id, String name) {
  4. super(id, name);
  5. }
  6. public Student(int id, String name, double score) {
  7. super(id, name);
  8. this.score = score;
  9. }
  10. }

 这里我就是为了举例子,在People重写一个equals()方法:

1.判断是否为同一对象

2.将不是People类对象筛除

3.强转想比较的对象,并比较其成员变量

  1. public class People {
  2. private int id;
  3. private String name;
  4. public People(int id, String name) {
  5. this.id = id;
  6. this.name = name;
  7. }
  8. public boolean equals(Object obj){
  9. //1.同一对象判断
  10. if(obj == this)
  11. return true;
  12. //2.不是People类对象
  13. if(!(obj instanceof People))
  14. return false;
  15. //3.强转成People类对象,比较两个对象的id与name
  16. People p = (People)obj;
  17. return p.id == this.id && p.name.equals(this.name);
  18. }
  19. }

 随后我把样例主方法放在People类内分析,来更深刻理解一下:

  1. public class People {
  2. private int id;
  3. private String name;
  4. public boolean equals(Object obj){
  5. //同一对象判断
  6. if(obj == this)
  7. return true;
  8. //不是People类对象
  9. if(!(obj instanceof People))
  10. return false;
  11. //强转成People类对象
  12. People p = (People)obj;
  13. //比较两个对象的id与name
  14. return p.id == this.id && p.name.equals(this.name);
  15. }
  16. public People(int id, String name) {
  17. this.id = id;
  18. this.name = name;
  19. }
  20. public static void main(String[] args) {
  21. People p1 = new People(1,"zhangsan");
  22. System.out.println(p1.equals(p1));//p1与p1比较结果:true
  23. People p2 = new People(1,"zhangsan");
  24. System.out.println(p1.equals(p2));//p1与p2比较结果:true
  25. People p3 = new People(2,"lisi");
  26. System.out.println(p1.equals(p3));//p1与p3比较结果:false
  27. People p4 = new Student(1,"zhangsan",521);
  28. System.out.println(p1.equals(p4));//p1与p4比较结果:true
  29. People p5 = new Student(1,"zhangsan",125);
  30. System.out.println(p4.equals(p5));//p4与p5比较结果:true,但是注意因为咱们重写方法时候没有比较score的值以至于结果返回true
  31. }
  32. }

6.常用的String类内的方法:

阿玮老师说没有必要了解其内部代码,正常程序员肯定掌握内部代码的构成,因为咱们是面对对象编程,所以只需要知道方法即可。

(1)截取字符串:对象.substring(int index)

  1. public class Csdn1 {
  2. public static void main(String[] args) {
  3. String s1 = new String("hello");
  4. System.out.println(s1.substring(2));//llo
  5. }
  6. }

 (2)获取单个字符:对象.charAt(int index)

  1. public class Csdn1 {
  2. public static void main(String[] args) {
  3. String s1 = new String("hello");
  4. System.out.println(s1.charAt(1));//e
  5. }
  6. }

(3)按照字典序比较大小:对象1.compareTo(对象2) 

  1. public class Csdn1 {
  2. public static void main(String[] args) {
  3. String s1 = new String("hello");
  4. String s2 = new String("hellp");
  5. System.out.println(s1.compareTo(s2));//-1
  6. }
  7. }
  1. public class Csdn1 {
  2. public static void main(String[] args) {
  3. String s1 = new String("hello");
  4. String s2 = new String("hella");
  5. System.out.println(s1.compareTo(s2));//14
  6. }
  7. }

 还有一些格式化字符串,在这里就不给大家介绍了(狗头)。

 三.StringBuilder类

StringBuilder可以看成是个容器,创建之后里面的内容是可变的

1.构造方法:

  1. public class Csdn1 {
  2. public static void main(String[] args) {
  3. StringBuilder sb = new StringBuilder("abc");
  4. System.out.println(sb);//abc
  5. }
  6. }

2.类内方法:

 下面根据代码进行解析:

  1. public class Csdn1 {
  2. public static void main(String[] args) {
  3. StringBuilder sb = new StringBuilder("abc");
  4. //注意:因为Java在底层对这个类做了一些特殊处理,打印的对象不是地址值,而是属性值
  5. System.out.println(sb);//abc
  6. sb.append("def");
  7. System.out.println(sb);//abcdef
  8. sb.reverse();
  9. System.out.println(sb);//fedcba
  10. System.out.println(sb.length());//6
  11. System.out.println(sb.toString());//fedcba
  12. }
  13. }

3.链式编程:

当我们调用方法时候,不需要用变量接收其结构,可以继续在此基础上调用其他方法:

  1. public class Csdn1 {
  2. public static void main(String[] args) {
  3. StringBuilder sb = new StringBuilder("abc").append("d").reverse();
  4. System.out.println(sb.toString());//dcba
  5. }
  6. }

4.源码分析:

最开始的StringBuilder默认容量为16,如果超过容量则自动扩增其(原来的容量*2 + 2),如果扩容不够,则会以实际长度为准。

下面看测试案例:

  1. public class Csdn1 {
  2. public static void main(String[] args) {
  3. StringBuilder sb = new StringBuilder();
  4. //打印容量:最多装多少
  5. System.out.println(sb.capacity());//16
  6. //打印长度:目前装多少
  7. System.out.println(sb.length());//0
  8. sb.append("qwertyuiopasdfghj");
  9. System.out.println(sb.capacity());//34 = 16 * 2 + 2
  10. System.out.println(sb.length());//17
  11. sb.append("klzxcvbnmqqwertyuiopas");
  12. System.out.println(sb.capacity());//70 = 34 * 2 + 2
  13. System.out.println(sb.length());//39
  14. }
  15. }

四.StringJoiner类

 StringJoiner跟StringBuilder一样,可以看成容器,创建之后里面内容可变的,能够提高字符串操作效率,代码简洁。

1.构造方法:

  1. import java.util.StringJoiner;
  2. public class Csdn1 {
  3. public static void main(String[] args) {
  4. StringJoiner sj = new StringJoiner("-","[","]");
  5. System.out.println(sj);//[]
  6. }
  7. }

这个相比于StringBuilder,其可以自己定义间隔符号以及头尾符号

2.类内方法:

通过下面代码进行分析理解吧,不过多解释了: 

  1. import java.util.StringJoiner;
  2. public class Csdn1 {
  3. public static void main(String[] args) {
  4. StringJoiner sj = new StringJoiner("-","[","]");
  5. //同样这里也是可以进行链式编程的
  6. sj.add("a").add("b").add("c");
  7. System.out.println(sj);//[a-b-c]
  8. System.out.println(sj.length());//7
  9. System.out.println(sj.toString());//[a-b-c]
  10. }
  11. }

好了,今天分享到这里了,下次会继续更新Java的相关内容,期待你的三连支持。

如果有没有理解的知识欢迎在评论区留言。

你的关注也是我更新的动力,同时也希望看看我的Java专栏以及其他专栏,多多支持。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/575717
推荐阅读
相关标签
  

闽ICP备14008679号