Java字符串
创始人
2024-05-21 21:01:05
0

文章目录

  • Java字符串
    • 一、Java常用 API
    • 二、String 类
      • 1. String 类的特点
        • 1)Java 程序中所有双引号字符串, 都是 String 类的对象
        • 2)字符串在创建之后, 其内容不可更改
        • 3)字符串虽然不可改变, 但是可以被共享
      • 2. String 类的常见构造方法
      • 3. String 类的常见面试题
      • 4. String 类用于比较的方法
      • 5. String 字符串的遍历
      • 6. String 字符串的截取方法
      • 7. String 字符串的替换方法
      • 8. String 字符串的切割方法
      • 9. String 方法小结
    • 三、StringBuilder 类
      • 1. StringBuiler 引入
      • 2. StringBuiler
      • 3. StringBuiler 构造方法
      • 4. StringBuiler 常用方法
        • 1)public StringBuilder append (任意类型):
        • 2)public StringBuilder reverse()
        • 3)public int length()
        • 4)public String toString()
      • 5. StringBuilder 案例
        • 1)对称字符串
        • 2)拼接字符串
        • 2)拼接字符串

Java字符串

一、Java常用 API

API (Application Programming Interface) :应用程序编程接口,就是别人写好的一些类,给咱们程序员直接拿去调用即可解决问题的

我们前面已经学过的 API 有 Scanner、Random。

但是 Java 中还有很多我们没有学习的类,下图仅一小部分:

image-20230130171837762

但要我们要记住这些类是比较困难的。

image-20230130171940065

这里我们可以使用 Java API 帮助文档来帮助我们使用这些类。

API 帮助文档使用流程:

  1. 在索引位置搜索自己要查看的类

  2. 看包

    目的:是 java.lang包(核心包),不需要导包代码(import);不是java.lang包,都需要编写导包代码。

  3. 看这个类的介绍

    目的:搞清楚这个类的作用

  4. 看这个类的构造方法

    目的:为了将该类的对象,创建出来

  5. 看这个类的成员方法(方法摘要)

    1. 方法名
    2. 参数
    3. 返回值
    4. 介绍

二、String 类

字符串在开发中的应用场景:

  • 比如,我们打开浏览器,登录 b站,需要输入账号名、密码、验证码等,这些就使用到了字符串。

    image-20230130172910495

  • 在游戏中的语言屏蔽机制

    image-20230130172950199

    玩家在输入时文字时语言不文明:

    image-20230130173105527

    可以对特定的字符串进行替换:

    image-20230130173144776

1. String 类的特点

  • Java 程序中所有双引号字符串, 都是 String 类的对象
  • 字符串在创建之后, 其内容不可更改
  • 字符串虽然不可改变, 但是可以被共享

1)Java 程序中所有双引号字符串, 都是 String 类的对象

package cn.edu.hgu.string;public class StringDemo1 {public static void main(String[] args) {String s = "abc";System.out.println(s.toUpperCase());System.out.println("helloworld".toUpperCase());}
}

输出结果为:

image-20230130193415037

2)字符串在创建之后, 其内容不可更改

如果想要更改,只能使用新的对象,做替换。

package cn.edu.hgu.string;public class StringDemo1 {public static void main(String[] args) {String s = "abc";System.out.println(s.hashCode());//输出对象的哈希码s = "def";System.out.println(s.hashCode());}
}

输出结果为:

image-20230130202642662

我们可以看到,两个数的值是不相同的,说明对象进行了替换。

3)字符串虽然不可改变, 但是可以被共享

下面我们来引入一个概念:字符串常量池

字符串常量池:当我们使用双引号创建字符串对象时,会检查常量池中是否存在该数据

  • 不存在:创建
  • 存在:复用

我们通过代码来看一下:

package cn.edu.hgu.string;public class StringDemo1 {public static void main(String[] args) {String s1 = "abc";System.out.println(s1.hashCode());//输出对象的哈希码String s2 = "abc";System.out.println(s2.hashCode());}
}

2. String 类的常见构造方法

构造方法说明
public String()创建空白字符串,不含任何内容
public String(String original)根据传入的字符串,创建字符串对象
public String(char[] chs)根据字符数组,创建字符串对象

下面我们来通过代码来使用一下这三个构造方法:

package cn.edu.hgu.string;public class StringDemo2 {public static void main(String[] args) {// public String():创建空白字符串,不含任何内容String s1 = new String();System.out.println(s1);// public String(char[] chs):根据传入的字符数组,创建字符串对象char[] chs = {'a', 'b', 'c'};String s2 = new String(chs);System.out.println(s2);// public String(String original):根据传入的字符串,来创建字符对象String s3 = new String("qwer");System.out.println(s3);}
}

输出结果为:

image-20230130204329246

注意事项

  • 这三个构造方法,创建字符串对象,都没有双引号直接创建来的方便。

    String s = “abc”;

  • 打印对象名,会看到对象的内存地址,这里打印字符串对象,为什么没有看到地址值?

3. String 类的常见面试题

面试题1:下面代码结果为:

public class StringTest1 {public static void main(String[] args) {String s1 = "abc";String s2 = "abc";System.out.println(s1 == s2);//true}
}

image-20230130212306607

因为两个变量使用的都是在字符变量池中的同一个变量地址。

面试题2:下面代码结果为:

public class StringTest1 {public static void main(String[] args) {String s1 = "abc";String s2 = new String("abc");System.out.println(s1 == s2);//false}
}

image-20230130212835608

s1使用的是字符串中的地址,而s2会在堆内存中新开辟一块内存地址,两个地址是不一样的。

面试题3:下面代码结果为:

public class StringTest1 {public static void main(String[] args) {String s1 = "abc";String s2 = "ab";String s3 = s2 + "c";System.out.println(s1 == s3);//false}
}

image-20230130213625791

s1使用的是在字符串常量池中的地址,字符串进行拼接时会使用 StringBuilder 类,拼接完成后会使用 toString 方法再堆内存中开辟一块地址,两个地址是不相同的。

面试题4:下面代码结果为:

public class StringTest1 {public static void main(String[] args) {String s1 = "abc";String s2 = "a" + "b" + "c";System.out.println(s1 == s2);//true}
}

前面讲了字符串在拼接时会调用 StringBuilder 类进行拼接,那为什么结果不对呢?

String s2 = “a” + “b”+“c”;编译器将这个"a" + “b”+“c"作为常量表达式,在编译时进行优化,直接取表达式结果"abc”,这里没有创建新的对象,而是从JVM字符串常量池中获取之前已经存在的"abc"对象。因此a,b具有对同一个string对象的引用,两个引用相等,结果true。

4. String 类用于比较的方法

public boolean  equals方法(要比较的字符串)                                完全一样结果才是true,否则为false public boolean  equalsIgnoreCase(要比较的字符串)		忽略大小写的比较

下面我们通过案例来学习这两个用于比较的方法:

package cn.edu.hgu.string.method;public class StringMethodDemo1 {public static void main(String[] args) {String s1 = "abc";String s2 = new String("abc");System.out.println(s1 == s2);//falseSystem.out.println(s1.equals(s2));//trueSystem.out.println("--------------");String ss1 = "abc";String ss2 = "ABC";System.out.println(ss1.equals(ss2));//falseSystem.out.println(ss1.equalsIgnoreCase(ss2));//true}
}

输出结果为:

image-20230130220546337

案例:用户登录

需求:已知正确的用户名和密码,请用程序实现模拟用户登录。总共给三次机会,登录之后,给出相应的提示。

分析:

  1. 定义两个字符串类型变量,模拟已经存在的用户名和密码
  2. 键盘录入用户输入的用户名,密码
  3. 比对

代码实现:

package cn.edu.hgu.test;import java.util.Scanner;public class StringTest1 {public static void main(String[] args) {Scanner sc = new Scanner(System.in);// 1.定义两个字符串类型变量,模拟已经存在的用户名和密码String username = "admin";String password = "123456";for (int i = 1; i <= 3; i++) {// 2. 键盘录入用户输入的用户名,密码System.out.println("请输入用户名:");String inputUsername = sc.nextLine();System.out.println("请输入密码:");String inputPassword = sc.nextLine();// 3.比对if (inputUsername.equals(username) && inputPassword.equals(password)) {System.out.println("登录成功!");break;} else {if (i == 3) {System.out.println("明儿再来吧~");} else {System.out.println("登陆失败,您还剩余" + (3 - i) + "次机会");}}}}
}

输出结果为:

image-20230130222419905

image-20230130222536579

5. String 字符串的遍历

public char[]  toCharArray ()    将字符串转换为字符数组 
public char chatAt (int index)  根据索引找字符
public int length() : 返回字符串的长度

下面我们来简单了解一下这几个方法的使用:

package cn.edu.hgu.string.method;public class StringMethodDemo2 {public static void main(String[] args) {String s = "itheima";char[] chars = s.toCharArray();for (int i = 0; i < chars.length; i++) {System.out.println(chars[i]);}System.out.println("-----------------");for (int i = 0; i < s.length(); i++) {char c = s.charAt(i);System.out.println(c);}}
}

输出结果为:

image-20230130223525251

案例:统计字符次数

需求 : 键盘录入一个字符串,统计该字符串中大写字母字符,小写字母字符,数字字符出现的次数(不考虑其他字符)

例如 : aAb3&c2B*4CD1

小写字母 : 3个

大写字母 : 4个

数字字母 : 4个

代码实现:

package cn.edu.hgu.test;import java.util.Scanner;public class StringTest2 {public static void main(String[] args) {// 1. 键盘录入一个字符串Scanner sc = new Scanner(System.in);System.out.println("请输入:");String content = sc.nextLine();// 2. 定义三份计数器变量,用于统计操作int smallCount = 0;int bigCount = 0;int numCount = 0;// 3.遍历字符串,获取到每一个字符char[] chars = content.toCharArray();for (int i = 0; i < chars.length; i++) {char c = chars[i];// 4.在遍历的过程中,加入 if 判断,看字符属于哪一种类别if (c >= 'a' && c <= 'z') {// 5.对应的计数器变量自增smallCount++;} else if (c >= 'A' && c <= 'Z') {bigCount++;} else if (c >= '0' && c <= '9') {numCount++;}}// 6.在遍历结束后,将统计好的计数器变量,打印在控制台System.out.println("小写字母:" + smallCount + "个");System.out.println("大写字母:" + bigCount + "个");System.out.println("数字字符:" + numCount + "个");}
}

输出结果为:

image-20230130225209151

6. String 字符串的截取方法

public String substring(int beginIndex, int endIndex)     截取注意点:包头不包尾,包左不包右只有返回值才是截取的小串
public String substring(int beginIndex)     截取到末尾

下面我们来了解一下这两个方法:

package cn.edu.hgu.string.method;public class StringMethodDemo3 {public static void main(String[] args) {String s = "itheima";String result1 = s.substring(2);System.out.println(result1);System.out.println("----------");String result2 = s.substring(0, 2);System.out.println(result2);}
}

输出结果为:

image-20230130225819918

注意:截取出来的内容,是作为新的字符串返回,别忘记找变量接收

案例:手机号屏蔽

需求:以字符串的形式从键盘接受一个手机号,将中间四位号码屏蔽,最终效果为:156****1234

分析:

  1. 键盘录入字符串
  2. 截取前三位
  3. 截取后四位
  4. 前三位 + “****” +后四位

代码实现:

package cn.edu.hgu.test;import java.util.Scanner;public class StringTest3 {public static void main(String[] args) {// 1.键盘录入字符串Scanner sc = new Scanner(System.in);System.out.println("请输入手机号:");String tel = sc.nextLine();// 2. 截取前三位String start = tel.substring(0, 3);// 3. 截取后四位String end = tel.substring(7);// 4. 前三位 + "****" +后四位System.out.println(start + "****" + end);}
}

输出结果为:

image-20230131084340548

7. String 字符串的替换方法

public String replace(旧值,新值)  替换注意点:返回值才是替换之后的结果

下面我们来学习一下这个方法:

package cn.edu.hgu.string.method;public class StringMethodDemo4 {public static void main(String[] args) {String s = "itheima";System.out.println("原字符串为:" + s);String result = s.replace("heima", "baima");System.out.println("替换后的字符串为:" + result);}
}

输出结果为:

image-20230131084847033

案例:敏感词替换

需求:键盘录入一个 字符串,如果字符串中包含(TMD),则使用 *** 替换

示例:

辅助你 TMD 是不是有病,  你出无尽干什么 ?
辅助你 *** 是不是有病,  你出无尽干什么 ?

代码实现:

package cn.edu.hgu.test;import java.util.Scanner;public class StringTest4 {/*需求:键盘录入一个字符串,如果字符串中包含(TMD),则使用 *** 替换*/public static void main(String[] args) {Scanner sc = new Scanner(System.in);System.out.println("请输入:");String content = sc.nextLine();content = content.replace("TMD", "***");System.out.println(content);}
}

输出结果为:

image-20230131090030403

8. String 字符串的切割方法

public String[] split(String regex) :根据传入的字符串作为规则进行切割将切割后的内容存入字符串数组中,并将字符串数组返回

下面我们来学习一下字符串的切割方法:

package cn.edu.hgu.string.method;public class StringMethodDemo5 {public static void main(String[] args) {String s1 = "192,168,1,1";String[] sArr1 = s1.split(",");for (int i = 0; i < sArr1.length; i++) {System.out.println(sArr1[i]);}String s2 = "192.168.1.1";String[] sArr2 = s2.split("\\.");for (int i = 0; i < sArr2.length; i++) {System.out.println(sArr2[i]);}}
}

输出结果为:

image-20230131093955483

建议:先正常指定切割规则,后来发现没有得到自己要的效果,就可以尝试在规则前面,加入 \

9. String 方法小结

public boolean  equals方法 (要比较的字符串)  :  比较内容
public boolean  equalsIgnoreCase (要比较的字符串) : 比较内容, 忽略大小写
public char[]  toCharArray ()    将字符串转换为字符数组 
public char chatAt (int index)  根据索引找字符
public int length() : 返回字符串的长度
public String substring(int beginIndex)     截取到末尾
public String substring(int beginIndex, int endIndex)     根据开始和结束索引做截取, 包含头不包含尾
public String replace(旧值,新值)  替换
public String[] split(String regex) :切割

三、StringBuilder 类

1. StringBuiler 引入

提高字符串操作效率

我们通过一段代码来看一下是否能提高操作效率:

package cn.edu.hgu.stringbuilder;public class StringBuilderDemo1 {public static void main(String[] args) {long time1 = getTime1();long time2 = getTime2();System.out.println("第一次用时:" + time1 + "毫秒");System.out.println("第二次用时:" + time2 + "毫秒");}private static long getTime2() {long start = System.currentTimeMillis();StringBuilder sb = new StringBuilder();for (int i = 1; i <= 10000; i++) {sb.append(i);}System.out.println(sb);long end = System.currentTimeMillis();long time = end - start;return time;}private static long getTime1() {// 获取1970年1月1日0分0秒到现在所经历的毫秒值(1秒 = 1000毫秒)long start = System.currentTimeMillis();String s = "";for (int i = 1; i <= 10000; i++) {s += i;}System.out.println(s);long end = System.currentTimeMillis();long time = end - start;return time;}
}

输出结果为:

image-20230131095726487

可以看到,使用 StringBuilder 类用时明显少于 String 类。

2. StringBuiler

StringBuilder是一种可变的字符序列

package cn.edu.hgu.stringbuilder;public class StringBuilderDemo2 {public static void main(String[] args) {StringBuilder sb = new StringBuilder();System.out.println(sb);sb.append("红色");System.out.println(sb);sb.append("绿色");System.out.println(sb);sb.append("蓝色");System.out.println(sb);}
}

输出结果为:

image-20230131102948399

StringBuilder是字符串的缓冲区, 我们可以将其理解为是一种容器,这个容器可以存储任意数据类型,但只要进入到这个容器,全部变成字符串。

package cn.edu.hgu.stringbuilder;public class StringBuilderDemo2 {public static void main(String[] args) {StringBuilder sb = new StringBuilder();sb.append(100);sb.append(45.6);sb.append(false);sb.append('中');sb.append("黑马程序员");System.out.println(sb);}
}

输出结果为:

image-20230131102729395

3. StringBuiler 构造方法

构造方法说明
public StringBuilder()创建一个空的字符串缓冲区(容器),其初始容量为16个字符
public StringBuilder(String str)创建一个字符串缓冲区, 并初始化好指定的参数内容

4. StringBuiler 常用方法

方法名说明
public StringBuilder append (任意类型)添加数据,并返回对象本身
public StringBuilder reverse()反转容器中的内容
public int length()返回长度 ( 字符出现的个数)
public String toString()通过toString()就可以实现把StringBuilder转换为String

1)public StringBuilder append (任意类型):

添加数据,并返回对象本身

package cn.edu.hgu.stringbuilder;public class StringBuilderDemo3 {public static void main(String[] args) {StringBuilder sb = new StringBuilder();StringBuilder sb2 = sb.append("绿色");StringBuilder sb3 = sb.append("红色");StringBuilder sb4 = sb.append("蓝色");System.out.println(sb == sb2);System.out.println(sb2 == sb3);System.out.println(sb3 == sb4);System.out.println(sb4 == sb);}
}

输出结果为:

image-20230131103729996

因为该方法返回对象本身,那么我们可以使用链式编程来简化代码:

package cn.edu.hgu.stringbuilder;public class StringBuilderDemo3 {public static void main(String[] args) {StringBuilder sb = new StringBuilder();// 链式编程:调用的方法,返回的结果是对象,就可以继续向下调用方法sb.append("绿色").append("红色").append("蓝色");System.out.println(sb);}
}

2)public StringBuilder reverse()

反转容器中的内容

package cn.edu.hgu.stringbuilder;public class StringBuilderDemo3 {public static void main(String[] args) {StringBuilder sb = new StringBuilder();// 链式编程:调用的方法,返回的结果是对象,就可以继续向下调用方法sb.append("绿色").append("红色").append("蓝色");System.out.println(sb);sb.reverse().append("你好");System.out.println(sb);}
}

输出结果为:

image-20230131111034759

3)public int length()

返回长度

package cn.edu.hgu.stringbuilder;public class StringBuilderDemo3 {public static void main(String[] args) {StringBuilder sb = new StringBuilder();// 链式编程:调用的方法,返回的结果是对象,就可以继续向下调用方法sb.append("绿色").append("红色").append("蓝色");System.out.println(sb);System.out.println(sb.length());//6}
}

4)public String toString()

通过toString()就可以实现把StringBuilder转换为String

package cn.edu.hgu.stringbuilder;public class StringBuilderDemo3 {public static void main(String[] args) {StringBuilder sb = new StringBuilder();// 链式编程:调用的方法,返回的结果是对象,就可以继续向下调用方法sb.append("绿色").append("红色").append("蓝色");System.out.println(sb);// 情况:我数据在StringBuilder当中,我要调用的方法,StringBuilder没有,但String有// 解决:转换为String类,再调用String[] sArr = sb.toString().split("色");for (int i = 0; i < sArr.length; i++) {System.out.println(sArr[i]);}}
}

5. StringBuilder 案例

1)对称字符串

需求:键盘接受一个字符串,程序判断出该字符串是否是对称字符串(回文字符串),并在控制台打印是或不是

  • 对称字符串:123321、111

  • 非对称字符串:123123

思路:对拿到的字符串进行反转,反转后的内容,根原数据相同,判定为回文字符串

代码实现:

package cn.edu.hgu.test;import java.util.Scanner;public class StringBuilderTest1 {/*需求:键盘接受一个字符串,程序判断出该字符串是否是对称字符串(回文字符串),并在控制台打印是或不是*/public static void main(String[] args) {Scanner sc = new Scanner(System.in);System.out.println("请输入一个字符串:");String content = sc.nextLine();// 将String类型转换为StringBuilder类型,为了调用内部反转的方法StringBuilder sb = new StringBuilder(content);String s = sb.reverse().toString();// 判断反转后的内容,和原数据是否相同if (content.equals(s)) {System.out.println("是对称字符串");} else {System.out.println("不是对称字符串");}}
}

输出结果为:

image-20230131112622415

String类型和StringBuilder类型互相转换:

String ---> StringBUilderString s = "abc";StringBuilder sb = new Stringbuilder(sb);
StringBuilder ---> StringString s = sb.toString();

2)拼接字符串

需求:定义一个方法,把 int 数组中的数据按照指定的格式拼接成一个字符串返回。

调用该方法,并在控制台输出结果。

例如:数组为int[] arr = {1,2,3};

执行方法后的输出结果为:[1, 2, 3]

代码实现:

package cn.edu.hgu.test;public class StringBuilderTest2 {public static void main(String[] args) {int[] arr = {1, 2, 3};StringBuilder result = arrayToString(arr);System.out.println(result);}private static StringBuilder arrayToString(int[] arr) {// 1.创建StringBuilder,准备进行拼接StringBuilder sb = new StringBuilder("[");// 2.遍历数组,获取内部元素for (int i = 0; i < arr.length - 1; i++) {// 3.将获取到的元素,拼接到字符串缓冲区sb.append(arr[i]).append(", ");}// 4.特殊处理最后一个元素sb.append(arr[arr.length - 1]).append("]");return sb;}}

输出结果为:

image-20230131114405983

参考文章:

Java中的常量优化机制
c";

  	StringBuilder sb = new Stringbuilder(sb);

StringBuilder —> String
String s = sb.toString();

2)拼接字符串

需求:定义一个方法,把 int 数组中的数据按照指定的格式拼接成一个字符串返回。

调用该方法,并在控制台输出结果。

例如:数组为int[] arr = {1,2,3};

执行方法后的输出结果为:[1, 2, 3]

代码实现:

package cn.edu.hgu.test;public class StringBuilderTest2 {public static void main(String[] args) {int[] arr = {1, 2, 3};StringBuilder result = arrayToString(arr);System.out.println(result);}private static StringBuilder arrayToString(int[] arr) {// 1.创建StringBuilder,准备进行拼接StringBuilder sb = new StringBuilder("[");// 2.遍历数组,获取内部元素for (int i = 0; i < arr.length - 1; i++) {// 3.将获取到的元素,拼接到字符串缓冲区sb.append(arr[i]).append(", ");}// 4.特殊处理最后一个元素sb.append(arr[arr.length - 1]).append("]");return sb;}}

输出结果为:

image-20230131114405983

参考文章:

Java中的常量优化机制

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
一帆风顺二龙腾飞三阳开泰祝福语... 本篇文章极速百科给大家谈谈一帆风顺二龙腾飞三阳开泰祝福语,以及一帆风顺二龙腾飞三阳开泰祝福语结婚对应...
美团联名卡审核成功待激活(美团... 今天百科达人给各位分享美团联名卡审核成功待激活的知识,其中也会对美团联名卡审核未通过进行解释,如果能...