Java基础快速入门: 字符串String

本文纲要

  1. API概述与帮助文档使用
  2. 键盘录入字符串
  3. String类概述
  4. String类的常见构造方法
  5. 创建字符串对象的区别对比
  6. String的特点与常见面试题
  7. 字符串的比较
  8. 案例:用户登录
  9. 字符串的遍历
  10. 统计字符次数
  11. 手机号屏蔽 —— 字符串截取
  12. 敏感词替换 —— 字符串替换
  13. 切割字符串
  14. String常用方法总结
  15. 总结

什么是API?

API(Application Programming Interface,应用程序编程接口)指的是厂商或平台提前编写好并提供给开发者使用的类与方法。简单来说,API就是别人已经写好的代码,我们只需按照约定去调用即可,不用关心底层的实现细节。

Java的API就是JDK中提供的各种功能的Java类。这些类把底层实现封装了起来,我们只需要学习如何使用它们即可。
使用API帮助文档

API帮助文档相当于一本字典,用来查阅类的使用方式。Java官方文档通常是英文版,汉化版中1.6版本的翻译质量较好,常用于学习。

使用步骤:

  1. 打开帮助文档,点击“显示”,在索引输入框中输入要学习的类名(如Random、Scanner)。
  2. 进入类页面后,先看类的包名(用于导包)。
  3. 阅读类的描述,了解该类的作用。
  4. 查看构造方法,掌握如何创建对象。
  5. 查看方法摘要,关注方法名、参数、返回值以及方法说明。
  6. 结合文档尝试编写代码。

注意:API是概念,API帮助文档是操作手册,不要混为一谈。

键盘录入字符串

使用Scanner类可以从键盘接收字符串数据。常用方法有两个:
next():遇到空格或制表符(tab)就停止读取,可能造成数据丢失。
nextLine():以回车换行符作为结束标记,可以完整读取一行数据。

代码示例:

import java.util.Scanner;
 
public class Demo1Scanner {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入:");
        String s = sc.nextLine();   // 使用nextLine完整读取 
        System.out.println(s);
    }
}

注意事项:
当同时使用 nextInt()nextLine() 时,nextLine() 会读取到前一个输入遗留的回车换行符,导致无法正常接收新数据。此时可以统一使用 next() 来接收字符串,或者额外调用一次 nextLine() 清除缓冲区。但在实际开发中,键盘录入主要用于学习阶段,真正项目中数据采集会通过网页表单等方式实现。

String类概述

String 类位于java.lang包下,该包是核心包,使用其中的类时不需要手动导包。

特点:

  1. 所有双引号字符串都是String类的对象。例如 “abc” 就是一个String对象,可以直接调用String的方法。
  2. 字符串是常量,创建后不可更改。对字符串的修改实际上是重新创建了一个新的字符串对象并让变量指向它,原字符串内容并未发生改变。
public class Demo1String {
    public static void main(String[] args) {
        String s1 = "abc123";
        System.out.println(s1.length());   // 6 
 
        s1 = "def";   // s1指向了新的对象,原"abc123"对象不变 
        System.out.println(s1);
    }
}

String类的常见构造方法

构造方法说明
new String()创建空白字符串对象
new String(char[] chs)根据字符数组创建字符串
new String(String original)根据传入的字符串创建新对象
String s = “abc”;直接双引号赋值(最常用)

代码示例:

public class Demo2StringConstructor {
    public static void main(String[] args) {
        String s1 = new String();               // 空字符串 
        System.out.println(s1);
 
        char[] chs = {'a', 'b', 'c'};
        String s2 = new String(chs);            // 由字符数组构造 
        System.out.println(s2);
 
        String s3 = new String("123");          // 根据字面值构造 
        System.out.println(s3);
    }
}

注意:打印String对象时,输出的是字符串内容而不是内存地址,这是String类特殊处理的结果

创建字符串对象的区别对比

双引号直接创建 —— 字符串常量池
使用双引号创建的字符串对象会存储在字符串常量池中
JVM会先检查常量池中是否已存在相同内容的字符串:

  • 如果不存在,则创建新对象并放入常量池;
  • 如果存在,则直接复用已有对象

new构造方法创建 —— 堆内存
每次使用new都会在堆内存中开辟新空间,即使内容相同,地址也不同

new方式

s3 = new String('abc')

堆内存分配新空间

s4 = new String('abc')

堆内存再次分配新空间

s3 指向堆地址1

s4 指向堆地址2

双引号方式

不存在

已存在

s1 = 'abc'

常量池检查

在常量池创建 'abc'

直接复用

s1 指向常量池地址

s2 指向同一常量池地址

代码验证

String s1 = "abc";
String s2 = "abc";
System.out.println(s1 == s2);   // true,常量池复用 
 
String s3 = new String("abc");
String s4 = new String("abc");
System.out.println(s3 == s4);   // false,堆中不同对象 

String的特点与常见面试题

1 ) 特点总结
Java中所有双引号字符串都是String类的对象。
字符串不可变,值创建后不能修改。
字符串可以共享(常量池机制)。

2 ) 常见面试题分析

题目1:

String s1 = "abc";
String s2 = "abc";
System.out.println(s1 == s2);   // true 

分析:s2创建时找到常量池已有"abc",直接复用。

题目2:

String s1 = "abc";
String s2 = new String("abc");
System.out.println(s1 == s2);   // false 

分析:s1指向常量池,s2指向堆内存,地址不同。而且 new String(“abc”) 实际创建了两个对象:常量池中的"abc"和堆中的new对象。

题目3:

String s1 = "abc";
String s2 = "ab";
String s3 = s2 + "c";
System.out.println(s1 == s3);   // false 

分析:当字符串拼接中包含变量时,底层会使用StringBuilder的append方法拼接,再调用toString生成新的String对象,该对象在堆内存中,与常量池中的"abc"地址不同。

题目4:

String s1 = "abc";
String s2 = "a" + "b" + "c";
System.out.println(s1 == s2);   // true 

分析:三个常量直接拼接,Java存在常量优化机制,编译时自动合并为"abc",所以s2同样指向常量池中的对象。

字符串的比较

使用 == 比较基本数据类型时比较的是数值,比较引用数据类型时比较的是地址值。
因此,比较字符串内容时不应该使用 ==,而应使用以下方法:

  • equals(Object obj):区分大小写地比较内容是否相同。
  • equalsIgnoreCase(String str):忽略大小写比较内容是否相同。

示例:

String s1 = "abc";
String s2 = "ABC";
System.out.println(s1.equals(s2));              // false 
System.out.println(s1.equalsIgnoreCase(s2));    // true 

案例:用户登录

需求: 已知用户名和密码,程序模拟用户登录,最多3次机会,登录成功或失败给出相应提示

实现思路:

  1. 定义已知用户名和密码(字符串常亮)。
  2. 键盘录入用户名和密码。
  3. 使用equals比较内容是否相同。
  4. 使用for循环控制3次机会,登录成功使用break提前结束

代码:

import java.util.Scanner;
 
public class Test1 {
    public static void main(String[] args) {
        String username = "admin";
        String password = "123456";
 
        Scanner sc = new Scanner(System.in);
        for (int i = 1; i <= 3; i++) {
            System.out.println("请输入用户名:");
            String scUsername = sc.nextLine();
            System.out.println("请输入密码:");
            String scPassword = sc.nextLine();
 
            if (username.equals(scUsername) && password.equals(scPassword)) {
                System.out.println("登录成功");
                break;
            } else {
                if (i == 3) {
                    System.out.println("登录次数已达上限,请明天再来");
                } else {
                    System.out.println("登录失败,您还剩余" + (3 - i) + "次机会");
                }
            }
        }
    }
}

字符串的遍历

遍历字符串即逐个获取其中的每一个字符。

1 ) 方法一:charAt + length

String s = "itheima";
for (int i = 0; i < s.length(); i++) {
    char c = s.charAt(i);
    System.out.println(c);
}

2 ) 方法二:toCharArray

String s = "itheima";
char[] chars = s.toCharArray();
for (int i = 0; i < chars.length; i++) {
    System.out.println(chars[i]);
}

推荐第二种方式,先将字符串转换为字符数组,再遍历数组,思路更清晰。

统计字符次数

需求: 键盘录入一个字符串,统计其中大写字母、小写字母、数字字符的出现次数

思路:

  1. 录入字符串,转换为字符数组
  2. 定义三个计数器
  3. 遍历字符,根据ASCII范围判断字符类型并累加

代码:

import java.util.Scanner;
 
public class Test4 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入:");
        String s = sc.nextLine();
        int bigCount = 0, smallCount = 0, numCount = 0;
 
        char[] chars = s.toCharArray();
        for (char c : chars) {
            if (c >= 'A' && c <= 'Z') {
                bigCount++;
            } else if (c >= 'a' && c <= 'z') {
                smallCount++;
            } else if (c >= '0' && c <= '9') {
                numCount++;
            }
        }
        System.out.println("大写字母:" + bigCount);
        System.out.println("小写字母:" + smallCount);
        System.out.println("数字:" + numCount);
    }
}

手机号屏蔽 —— 字符串截取

需求: 将手机号中间四位替换为 ****,如 15612341234156****1234

截取方法:

  • substring(int beginIndex):从beginIndex截取到末尾。
  • substring(int beginIndex, int endIndex):截取[beginIndex, endIndex)区间,包含头不包含尾

实现:

Scanner sc = new Scanner(System.in);
System.out.println("请输入手机号:");
String tel = sc.nextLine();
String start = tel.substring(0, 3);    // 前三位 
String end = tel.substring(7);         // 后四位 
System.out.println(start + "" + end);

敏感词替换 —— 字符串替换

需求: 将字符串中的敏感词 “TMD” 替换为 *

方法:

  • String replace(CharSequence target, CharSequence replacement):用新值替换旧值,返回新字符串。

代码:

Scanner sc = new Scanner(System.in);
System.out.println("请输入:");
String s = sc.nextLine();
String result = s.replace("TMD", "***");
System.out.println(result);

切割字符串

需求: 输入学生信息(如 “张三,23”),切割出姓名和年龄并封装为Student对象。

方法:

  • String[] split(String regex):根据传入的正则表达式切割字符串,返回字符串数组。

步骤:

  1. 创建Student实体类(domain包下)。
  2. 录入字符串,用逗号切割。
  3. 取出数组元素,通过构造器封装对象并输出。

Student类:

public class Student {
    private String name;
    private String age;
    // 空参、有参构造、getter/setter 省略 
}

主程序:

Scanner sc = new Scanner(System.in);
System.out.println("请输入学生信息:");
String stuInfo = sc.nextLine();
String[] arr = stuInfo.split(",");
Student stu = new Student(arr[0], arr[1]);
System.out.println(stu.getName() + "..." + stu.getAge());

String常用方法总结

方法名说明
equals(String)比较字符串内容(区分大小写)
equalsIgnoreCase(String)比较内容(忽略大小写)
length()返回字符串长度(字符个数)
charAt(int index)返回指定索引处的字符
toCharArray()将字符串转为字符数组
substring(int begin)从begin截取到末尾
substring(int begin, int end)截取[begin, end)范围内的子串
replace(old, new)用new替换所有old,返回新字符串
split(String regex)根据正则切割字符串,返回数组

总结

本文从API概念入手,逐步讲解了String类的特性、构造方法、常量池机制、常用方法,并通过案例加深理解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Wang's Blog

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

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

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

打赏作者

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

抵扣说明:

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

余额充值