强哥说Java--Java String和StringBuilder

简介: 强哥说Java--Java String和StringBuilder

Java String和StringBuilder


它作为Java语言的内置类,String类也为我们预先定义了很多好用的方法


前言


  1. Let·s get it
  2. 8/24,继续编程
  3. 不要停止向前,奥里给!!!
  4. 马上开学了,开学之前把Java的基础打牢了!!!


1. String 对象的创建


String对象的创建有两种方式。

第1 种方式就是我们最常见的创建字符串的方式:

 String str1 = "8/24";

第 2 种方式是对象实例化的方式,使用new关键字,并将要创建的字符串作为构造参数:

  String str2 = new String("8/25");

如果调用 String 类的无参构造方法,则会创建一个空字符串:

 String str3 = new String();

这种方式很少使用。


2. 获取字符串长度


可以使用length()方法来获取字符串的长度。例如:

实例演示

 package com.caq.oop.demo08;
 ​
 public class Test {
     public static void main(String[] args) {
         String str1 = "8/24";
         int a = str1.length();
         System.out.println(a);
        
     }
 }
 ​

运行结果:

 4

3. 字符串查找


3.1 获取指定位置字符


可以使用char charAt(int index)方法获取字符串指定位置的字符。它接收一个整型的index参数,指的是索引位置,那什么是索引位置呢?例如,有一字符串I love Java,其每个字符的索引如下图所示:

image.png

可以从图示中看出,索引下标从0开始。假如我们要获取字符C,则为方法传入参数2即可:

实例演示

 package com.caq.oop.demo08;
 ​
 public class Test {
     public static void main(String[] args) {
         String str1 = "ABCDEFG";
         char a = str1.charAt(4);
         System.out.println(a);
 ​
     }
 }
 ​

运行结果:

 E
  

3.2 查找字符串位置


这里介绍查找字符串位置的两个方法:

  • indexOf() 获取字符或子串在字符串中第一次出现的位置。
  • lasIndexOf() 获取字符或子串在字符串中最后一次出现的位置。

这里的子串指的就是字符串中的连续字符组成的子序列。例如,字符串Hello就是字符串Hello Java的子串。

indexOf()

1 获取字符在字符串中第一次出现的位置:

 package com.caq.oop.demo08;
 ​
 public class Test {
     public static void main(String[] args) {
         String str1 = "ABCDEFG";
         int a = str1.indexOf('G');
         System.out.println("字符A在字符串str1第一次出现的位置为:"+ a);
     }
 }
 ​
 字符A在字符串str1第一次出现的位置为:6

2 获取子串在字符串中第一次出现的位置:

 package com.caq.oop.demo08;
 ​
 public class Test {
     public static void main(String[] args) {
         String str1 = "I just poor boy,I needn`t sympathy";
         int a = str1.indexOf('I');
         System.out.println("字串I在字符串str1第一次出现的位置为:"+ a);
     }
 }

 字符I在字符串str1第一次出现的位置为:0

lastIndexOf()

1 获取字符在字符串中最后一次出现的位置:

package com.caq.oop.demo08;
public class Test {
    public static void main(String[] args) {
        String str1 = "I just poor boy,I needn`t sympathy";
        int a = str1.lastIndexOf("I");
        System.out.println("字串I在字符串str1最后一次出现的位置为:"+ a);
    }
}

字串I在字符串str1最后一次出现的位置为:16

2 获取子串在字符串中最后一次出现的位置:

package com.caq.oop.demo08;
public class Test {
    public static void main(String[] args) {
        String str1 = "I love LYF and I love PYY";
        int a = str1.lastIndexOf("I love");
        System.out.println("子串I love在字符串str1最后一次出现的位置为:"+ a);
    }
}

运行结果:

子串I love在字符串str1最后一次出现的位置为:15

需要特别注意的是,以上方法的参数都是区分大小写的。如果你找了个不存在的,上述方法都会返回一个整型值:-1。我们来看以下示例:

 package com.caq.oop.demo08;
 ​
 public class Test {
     public static void main(String[] args) {
         String str1 = "I love LYF and I love PYY";
         int a = str1.lastIndexOf("QQ");
         System.out.println("子串QQ在字符串str1最后一次出现的位置为:"+ a);
     }
 }
 ​

 子串QQ在字符串str1最后一次出现的位置为:-1

可以看到结果是-1


4. 字符串截取


字符串的截取也称为获取子串

可以使用substring()方法来获取子串

String类中有两个重载的实例方法:

  • String substring(int beginIndex) 获取从beginIndex位置开始到结束的子串。
  • String substring(int beginIndex, int endIndex) 获取从beginIndex位置开始到endIndex位置的子串(不包含endIndex位置字符)

image.png

关于这两个方法的使用,我们来看一个实例:

实例演示

 package com.caq.oop.demo08;
 ​
 public class Test {
     public static void main(String[] args) {
         String str1 = "I just poor boy,I need no sympathy";
         String a = str1.substring(15);
         String b = str1.substring(8,12);
         System.out.println("从15到最后的字符串"+ a);
         System.out.println("从8到12的字符串"+ b);
     }
 }

运行结果:

 从15到最后的字符串,I need no sympathy
 从8到12的字符串oor 

要特别注意,方法签名上有两个参数的substring(int beginIndex, int endIndex)方法

截取的子串不包含endIndex位置的字符。


5. 字符串切割


5.1 切割为字串数组


String[] split(String regex)方法可将字符串切割为子串,其参数regex是一个正则表达式分隔符,返回字符串数组。

例如,我们使用空格作为分隔符来切割I just poor boy,I need no sympathy字符串,结果将返回含有7个元素的字符串数组:

 package com.caq.oop.demo08;
 ​
 public class Test {
     public static void main(String[] args) {
         String str1 = "I just poor boy,I need no sympathy";
         String[] a = str1.split(" ");
         for (String index : a) {
             System.out.print(index+'\t');
         }
     }
 }

 I   just    poor    boy,I   need    no  sympathy

注意,有几种特殊的分隔符:* ^ : | . ``,要使用转义字符转义。例如:

 String[] a = str2.split("\*");
 ​
 String[] b = str3.split("\\");
 ​
 String[] c = str4.split("\|");

String[] split(String regex, int limit)

其第二个参数limit用以控制正则匹配被应用的次数


5.2 切割为 byte 数组


在实际工作中,网络上的数据传输就是使用二进制字节数据。因此字符串和字节数组之间的相互转换也很常用。

我们可以使用getBytes()方法将字符串转换为byte数组。例如:

实例演示

 package com.caq.oop.demo08;
 ​
 public class Test {
     public static void main(String[] args) {
         String str1 = "ABCD";
         byte[] a = str1.getBytes();
         for (byte index : a) {
             System.out.print(index + "\t");
         }
     }
 }
 ​

运行结果:

 65  66  67  68  

字节数组转换为字符串的方法很简单,直接实例化一个字符串对象,将字节数组作为构造方法的参数即可:

 // 此处的ascii为上面通过字符串转换的字节数组
 String s = new String(ascii);

6. 字符串大小写转换


字符串的大小写转换有两个方法:

  • toLowerCase() 将字符串转换为小写
  • toUpperCase() 将字符串转换为大写

我们来看一个实例:

实例演示

 package com.caq.oop.demo08;
 ​
 public class Test {
     public static void main(String[] args) {
         String str1 = "ABCD";
         String a = str1.toLowerCase();
         System.out.println("小写:"+a);
         String b = str1.toUpperCase();
         System.out.println("大写:"+b);
     }
 }
 ​

运行结果:

 小写:abcd
 大写:ABCD

试想,如果想把字符串HELLO world中的大小写字母互换,该如何实现呢?

这里可以结合字符串切割方法以及字符串连接来实现:

实例演示

 package com.caq.oop.demo08;
 ​
 public class Test {
     public static void main(String[] args) {
         String str1 = "AB CD";
         //先切割位数组
         String[] a = str1.split(" ");
         //通过索引,分别变为大写和小写
         String result = a[0].toLowerCase() + " " + a[1].toUpperCase();
         System.out.println(result);
     }
 }
 ​

运行结果:

 ab CD

当然,实现方式不止一种


7. 字符串比较


String类提供了boolean equals(Object object)方法来比较字符串内容是否相同,返回一个布尔类型的结果。

需要特别注意的是,在比较字符串内容是否相同时,必须使用equals()方法而不能使用==运算符。我们来看一个示例:

实例演示

 package com.caq.oop.demo08;
 ​
 public class Test {
     public static void main(String[] args) {
         String str1 = "AB CD";
         String str2 = new String("AB CD");
         String str3 = "AB CD";
 ​
 ​
         System.out.println(str1==str2);
         System.out.println(str1.equals(str2));
         System.out.println(str1==str3);
 ​
     }
 }
 ​

运行结果:

 false
 true
 true

代码中三个字符串str1str2str3的内容都是AB CD,因此使用equals()方法对它们进行比较,其结果总是为true

注意观察执行结果,其中使用==运算符比较str1str2的结果为true,但使用==运算符比较的str1str3的结果为false

这是因为==运算符比较的是两个变量的地址而不是内容。

我用图来解释一下!!!

1.当执行String str1 = "AB CD;"语句时,会在内存的栈空间中创建一个str1,在常量池中创建一个"AB CD",并将str1指向hello

当执行String str2 = "hello";语句时,栈空间中会创建一个str2,由于其内容与str1相同,会指向常量池中的同一个对象。所以str1str2指向的地址是相同的

这就是==运算符比较str1str2的结果为true的原因。

image.png


2.当执行String str3 = new String("hello");语句时,使用了new关键字创建字符串对象,由于对象的实例化操作是在内存的堆空间进行的,此时会在栈空间创建一个str3,在堆空间实例化一个内容为hello的字符串对象,并将str3地址指向堆空间中的hello,这就是==运算符比较str1str3的结果为false的原因。

image.png


8. 小结


我们介绍了 Java String类的常用方法:

  • 使用length()方法可以获取字符串长度;
  • 使用charAt()indexOf()以及lastIndexOf()方法可以对字符串进行查找;
  • substring()方法可以对字符串的进行截取,split()getBytes()方法可以将字符串切割为数组;
  • toLowerCase()toUpperCase()方法分别用于大小写转换,使用equals()方法对字符串进行比较,这里要注意,对字符串内容进行比较时,永远都不要使用==运算符。

这些方法大多有重载方法,实际工作中,要根据合适的场景选用对应的重载方法。!!!

奥里给就完了


1. StringBuilder 概述


1.1 什么是 StringBuilder


String 相似,StringBuilder 也是一个与字符串相关的类

Java 官方文档给 StringBuilder 的定义是:可变的字符序列。


1.2 为什么需要 StringBuilder


在 Java 字符串的学习中,我们知道了字符串具有不可变性,当频繁操作字符串时候,会在常量池中产生很多无用的数据

StringBuilderString 不同,它具有可变性。相较 String 类不会产生大量无用数据,性能上会大大提高。

因此对于需要频繁操作字符串的场景,建议使用 Stringbuilder 类来代替 String 类。


2. StringBuffer 概述


2.1 定义


了解了 StringBuilder 类 ,StringBuffer 也是不得不提的一个类,Java 官方文档给出的定义是:线程安全的可变字符序列。


2.2 与前者的区别


StringBufferStringBuilder 的前身,在早期的 Java 版本中应用非常广泛,它是 StringBuilder 的线程安全版本(线程我们将在后面的小节中介绍),但实现线程安全的代价是执行效率的下降

你可以对比 StringBuilderStringBuffer 的接口文档,它们的接口基本上完全一致。为了提升我们代码的执行效率,在如今的实际开发中 StringBuffer 并不常用。


3. StringBuilder 的常用方法


3.1 构造方法


StringBuilder 类提供了如下 4 个构造方法:

  1. StringBuilder() 构造一个空字符串生成器,初始容量为 16 个字符;
  2. StringBuilder(int catpacity) 构造一个空字符串生成器,初始容量由参数 capacity 指定;
  3. StringBuilder(CharSequence seq) 构造一个字符串生成器,该生成器包含与指定的 CharSequence 相同的字符。;
  4. StringBuilder(String str) 构造初始化为指定字符串内容的字符串生成器。

其中第 4 个构造方法最为常用,我们可以使用 StringBuilder 这样初始化一个内容为 hello 的字符串:

 package com.caq.oop.demo08;
 ​
 public class Test {
     public static void main(String[] args) {
         StringBuilder str = new StringBuilder("8/24");
         
     }
 }


3.2 成员方法


StringBuilder 类下面也提供了很多与 String 类相似的成员方法,以方便我们对字符串进行操作。下面我们将举例介绍一些常用的成员方法。

3.2.1 字符串连接

可以使用 StringBuilderStringBuilder append(String str) 方法来实现字符串的连接操作。

我们知道,String 的连接操作是通过 + 操作符完成连接的:

 String str1 = "Hello";
 String str2 = "World";
 String str3 = str1 + " " + str2;

如下是通过 StringBuilder 实现的字符串连接示例:

实例演示

 package com.caq.oop.demo08;
 ​
 public class Test {
     public static void main(String[] args) {
         StringBuilder str = new StringBuilder("8/24");
         str.append(" ");
         str.append("world");
         System.out.println(str);
     }
 }
 ​

运行结果:

 8/24 world

由于 append() 方法返回的是一个 StringBuilder 类型,我们可以实现链式调用。例如,上述连续两个 append() 方法的调用语句,可以简化为一行语句:

  //链式调用
 str.append(" ").append("world");

如果你使用 IDE 编写如上连接字符串的代码,可能会有下面这样的提示(IntelliJ idea 的代码截图):

image.png

提示内容说可以将 StringBuilder 类型可以替换为 String 类型,也就是说可以将上边地代码改为:

 String str = "8/24" + " " + "world";

这样写并不会导致执行效率的下降,这是因为 Java 编译器在编译和运行期间会自动将字符串连接操作转换为 StringBuilder 操作或者数组复制,间接地优化了由于 String 的不可变性引发的性能问题。

值得注意的是,append() 的重载方法有很多,可以实现各种类型的连接操作。例如我们可以连接 char 类型以及 float 类型,实例如下:

实例演示

 package com.caq.oop.demo08;
 ​
 public class Test {
     public static void main(String[] args) {
         StringBuilder str = new StringBuilder("zs的身高是");
         str.append(':').append(172.5f);
         System.out.println(str);
     }
 }
 ​

运行结果:

 zs的身高是:172.5

上面代码里连续的两个 append() 方法分别调用的是重载方法 StringBuilder append(char c)StringBuilder append(float f)

3.2.2 获取容量

可以使用 int capacity() 方法来获取当前容量,容量指定是可以存储的字符数(包含已写入字符),超过此数将进行自动分配。注意,容量与长度(length)不同,长度指的是已经写入字符的长度。

例如,构造方法 StringBuilder() 构造一个空字符串生成器,初始容量为 16 个字符。我们可以获取并打印它的容量,实例如下:

实例演示

 package com.caq.oop.demo08;
 ​
 public class Test {
     public static void main(String[] args) {
         // 调用StringBuilder的无参构造方法,生成一个str对象
         StringBuilder stringBuilder = new StringBuilder();
         System.out.println(stringBuilder.capacity());
         for (int i = 0; i < 17; i++) {
             stringBuilder.append(i);
         }
         System.out.println(stringBuilder.capacity());
     }
 }
 ​
 ​

运行结果:

 16
 34

3.2.3 字符串替换

可以使用 StringBuilder replace(int start, int end, String str) 方法,来用指定字符串替换从索引位置 start 开始到 end 索引位置结束(不包含 end)的子串。实例如下:

实例演示

 package com.caq.oop.demo08;
 ​
 public class Test {
     public static void main(String[] args) {
         // 调用StringBuilder的无参构造方法,生成一个str对象
         StringBuilder stringBuilder = new StringBuilder("Hello monkey");
         // 调用字符串替换方法,将 monkey 替换为 Jack
         stringBuilder.replace(6,12, "Jack");
         System.out.println(stringBuilder);
     }
 }

在IDEA里,是有提示的

运行结果:

image.png

 Hello Jack

也可使用 StringBuilder delete(int start, int end) 方法,先来删除索引位置 start 开始到 end 索引位置(不包含 end)的子串,再使用 StringBuilder insert(int offset, String str) 方法,将字符串插入到序列的 offset 索引位置。同样可以实现字符串的替换,例如:

 package com.caq.oop.demo08;
 ​
 public class Test {
     public static void main(String[] args) {
         // 调用StringBuilder的无参构造方法,生成一个str对象
         StringBuilder stringBuilder = new StringBuilder("Hello monkey");
         stringBuilder.delete(6,12);
         
         //从第6位开始插入,内容是Jack
         stringBuilder.insert(6,"Jack");
         System.out.println(stringBuilder);
     }
 }

3.2.4 字符串截取

可以使用 StringBuilder substring(int start) 方法来进行字符串截取,例如,我们想截取字符串的第7到第9个字符,实例如下:

实例演示

 package com.caq.oop.demo08;
 ​
 public class Test {
     public static void main(String[] args) {
         // 调用StringBuilder的无参构造方法,生成一个str对象
         StringBuilder stringBuilder = new StringBuilder("Hello monkey");
         String str = stringBuilder.substring(7, 9);
         System.out.println(str);
     }
 }

运行结果:

 on

3.2.5 字符串反转

可以使用 StringBuildr reverse() 方法,对字符串进行反转操作,例如:

实例演示

 package com.caq.oop.demo08;
 ​
 public class Test {
     public static void main(String[] args) {
         // 调用StringBuilder的无参构造方法,生成一个str对象
         StringBuilder stringBuilder = new StringBuilder("Hello monkey");
         System.out.println(stringBuilder.reverse());
     }
 }

运行结果:

 yeknom olleH


4. 小结


今天我们介绍了 Java 的 StringBuilder 类,它具有可变性,对于频繁操作字符串的场景,使用它来代替 String 类可以提高程序的执行效率;

也知道了 StringBufferStringBuilder 的线程安全版本

完结,撒花花~~~


相关文章
|
2月前
|
Java 索引
java基础(13)String类
本文介绍了Java中String类的多种操作方法,包括字符串拼接、获取长度、去除空格、替换、截取、分割、比较和查找字符等。
39 0
java基础(13)String类
|
30天前
|
Java 测试技术 开发者
Java零基础-indexOf(String str)详解!
【10月更文挑战第14天】Java零基础教学篇,手把手实践教学!
111 65
|
6天前
|
安全
String、StringBuffer、StringBuilder的区别
String 由 char[] 数组构成,使用了 final 修饰,对 String 进行改变时每次都会新生成一个 String 对象,然后把指针指向新的引用对象。 StringBuffer可变并且线程安全;有一定缓冲区容量,字符串大小没超过容量,不会重新分配新的容量,适合多线程操作字符串; StringBuiler可变并且线程不安全。速度比StringBuffer更快,适合单线程操作字符串。 操作少量字符数据用 String;单线程操作大量数据用 StringBuilder;多线程操作大量数据用 StringBuffer
|
1月前
|
存储 SQL 安全
Java零基础-StringBuilder类详解
【10月更文挑战第12天】Java零基础教学篇,手把手实践教学!
28 5
|
1月前
|
Java 测试技术 开发者
Java零基础-indexOf(String str)详解!
【10月更文挑战第13天】Java零基础教学篇,手把手实践教学!
41 1
|
1月前
|
存储 SQL 安全
Java零基础-StringBuilder类详解
【10月更文挑战第11天】Java零基础教学篇,手把手实践教学!
31 1
|
1月前
|
安全 Java 测试技术
Java零基础-StringBuffer 类详解
【10月更文挑战第9天】Java零基础教学篇,手把手实践教学!
28 2
|
2月前
|
安全 Java
String、StringBuffer、StringBuilder的区别
这篇文章讨论了Java中String、StringBuffer和StringBuilder的区别。String是不可变的,每次操作都会产生新的对象,效率低且浪费内存。StringBuilder可以在原字符串基础上进行操作,不开辟额外内存,弥补了String的缺陷。StringBuffer和StringBuilder类似,但StringBuffer的方法是线程安全的。文章还列举了StringBuffer的常用方法,并提供了使用示例代码。最后总结了这三者的主要区别。
String、StringBuffer、StringBuilder的区别
|
1月前
|
canal 安全 索引
(StringBuffer和StringBuilder)以及回文串,字符串经典习题
(StringBuffer和StringBuilder)以及回文串,字符串经典习题
37 5
|
1月前
|
IDE Java 开发工具
Java“未封闭的 String 表达式”怎么解决
要解决Java中的“未封闭的 String 表示”问题,需检查并修正字符串字面量,确保每个字符串被正确地用双引号括起来。若字符串跨越多行,可使用字符串连接操作符(+)或引入文本块(JDK 13 及以上版本)。这能帮助避免语法错误,并使代码更整洁易读。
下一篇
无影云桌面