Java 复习笔记 - 字符串篇

文章目录

  • 一,API和API帮助文档
    • (一)API
    • (二)API帮助文档
  • 二,String概述
  • 三,String构造方法代码实现和内存分析
  • 四,字符串的比较
  • 五,综合练习
    • (一)用户登录
    • (二)遍历字符串和统计字符个数
      • 1,遍历字符串
      • 2,统计字符个数
    • (三)字符串拼接和反转
      • 1,拼接字符串
      • 2,字符串反转
    • (四)金额转换
    • (五)手机号屏蔽
    • (六)身份证信息查看
    • (七)敏感词替换
  • 六,StringBuilder的基本操作
    • (一)StringBuilder概述
    • (二)StringBuilder常用方法
    • (三)练习 - 对称字符串
    • (四)练习 - 字符串拼接
  • 七,StringJoiner的基本操作
    • (一)StringJoiner概述
    • (二)StringJoiner的构造方法
    • (三)StringJoiner的成员方法
  • 八,字符串的相关底层原理
    • (一)扩展底层原理1:字符串存储的内存原理
    • (二)扩展底层原理2:==号比较的到底是多少?
    • (三)扩展底层原理3:字符串拼接的底层原理
    • (四)扩展底层原理4:StringBuilder提高效率原理图
    • (五)扩展底层原理5:StringBuilder代码分析
  • 九,综合练习
    • (一)阿拉伯数字转换罗马数字
    • (二)调整字符串的内容并比较
    • (三)打乱字符串内容
    • (四)生成验证码
    • (五)计算两数乘积


一,API和API帮助文档

(一)API

Java API(Application Programming Interface)是指Java提供的一组类和接口,用于支持开发者在Java平台上进行应用程序开发。Java API包含了众多的类和接口,涵盖了各种功能和领域,如集合框架、输入输出、网络通信、多线程、图形用户界面等。

以下是一些常用的Java API:

  1. java.lang:包含Java语言的核心类,如Object、String、Math等。
  2. java.util:提供了各种工具类和接口,如集合框架(List、Set、Map等)、日期时间处理、随机数生成、正则表达式等。
  3. java.io:用于进行输入输出操作的类和接口,如文件读写、流操作等。
  4. java.net:提供了网络通信相关的类和接口,如Socket、URL等。
  5. java.sql:用于数据库访问的类和接口,如连接数据库、执行SQL语句等。
  6. java.awt和javax.swing:用于创建图形用户界面的类和接口。
  7. java.concurrent:提供了并发编程相关的类和接口,如线程池、锁、并发集合等。
  8. java.security:提供了加密、数字签名、密钥管理等安全相关的类和接口。

除了以上列举的一些常用的Java API,还有许多其他的API可供开发者使用。开发者可以通过查阅Java官方文档或者IDE中的代码提示来了解更多的Java API,并根据自己的需求选择合适的API来实现所需功能。

(二)API帮助文档

  • Java17:https://docs.oracle.com/en/java/javase/17/docs/api/index.html
    Java 复习笔记 - 字符串篇_第1张图片
  • Class String
    Java 复习笔记 - 字符串篇_第2张图片

二,String概述

在Java中,字符串是一种不可变的对象,它是由字符序列组成的。Java中的字符串是由String类表示的。

字符串在Java中很常见,它们用于存储文本数据。Java字符串有以下特点:

  1. 不可变性:一旦创建了一个字符串对象,它就无法被修改。任何对字符串的修改操作都会创建一个新的字符串对象。

  2. 存储方式:字符串在内存中以Unicode编码方式存储。每个字符占用两个字节的内存空间。

  3. 字符串字面值:Java提供了使用双引号括起来的字符串字面值来表示字符串。例如:“Hello World”。

  4. 字符串连接:可以使用"+"操作符将多个字符串连接成一个新的字符串。

  5. 字符串常量池:Java中有一个字符串常量池,用于存储字符串字面值。当创建一个字符串对象时,首先检查常量池中是否存在相同字面值的字符串,如果存在,则返回常量池中的对象,否则创建一个新的字符串对象并添加到常量池中。

Java提供了许多用于操作字符串的方法,例如:

  • length():返回字符串的长度。
  • charAt(int index):返回指定索引位置的字符。
  • substring(int beginIndex, int endIndex):返回从beginIndex(包括)到endIndex(不包括)之间的子字符串。
  • equals(Object obj):比较字符串与指定对象是否相等。
  • indexOf(String str):返回指定字符串在当前字符串中第一次出现的索引位置。
  • toUpperCase():将字符串转换为大写。
  • toLowerCase():将字符串转换为小写。

这些是字符串的一些基本概念和操作。在实际开发中,我们经常需要使用字符串进行文本处理和操作。Java提供了强大的字符串处理功能,使得我们可以轻松地进行各种字符串操作。

三,String构造方法代码实现和内存分析

在Java中,String对象是不可变的,也就是说一旦创建就无法更改其内容。因此,String构造方法的实现中涉及到的内存分析主要是关于字符串对象的创建和存储。

  1. 使用字符串字面值创建字符串对象:
String str = "Hello World";

在这种情况下,Java会在字符串常量池中查找是否存在相同内容的字符串对象。如果存在,就将已有的对象引用赋给变量str;如果不存在,就在字符串常量池中创建一个新的字符串对象,并将其引用赋给变量str。

  1. 使用字符数组创建字符串对象:
char[] charArray = {'H', 'e', 'l', 'l', 'o'};
String str = new String(charArray);

在这种情况下,Java会在堆内存中创建一个新的字符串对象,并将传入的字符数组的内容复制到该对象的字符数组中。然后,将该对象的引用赋给变量str。

  1. 使用字节数组创建字符串对象:
byte[] byteArray = {72, 101, 108, 108, 111};
String str = new String(byteArray);

在这种情况下,Java会在堆内存中创建一个新的字符串对象,并将传入的字节数组的内容解码为字符,然后复制到该对象的字符数组中。然后,将该对象的引用赋给变量str。

  1. 使用指定字符集的字节数组创建字符串对象:
byte[] byteArray = {72, 101, 108, 108, 111};
String str = new String(byteArray, "UTF-8");

在这种情况下,Java会根据指定的字符集将字节数组解码为字符,并创建一个新的字符串对象。然后,将该对象的引用赋给变量str。

  1. 使用指定字符集的字节数组的一部分创建字符串对象:
byte[] byteArray = {72, 101, 108, 108, 111};
String str = new String(byteArray, 0, 3, "UTF-8");

在这种情况下,Java会根据指定的字符集将字节数组的指定部分解码为字符,并创建一个新的字符串对象。然后,将该对象的引用赋给变量str。

  1. 使用StringBuffer或StringBuilder对象创建字符串对象:
StringBuilder sb = new StringBuilder("Hello");
String str = new String(sb);

在这种情况下,Java会在堆内存中创建一个新的字符串对象,并将传入的StringBuilder或StringBuilder对象的内容复制到该对象的字符数组中。然后,将该对象的引用赋给变量str。

需要注意的是,由于String对象的不可变性,如果对字符串进行修改,实际上是创建了一个新的字符串对象。原始的字符串对象仍然存在于内存中,只是不再被引用,最终会被垃圾回收器回收。这也是Java中常用StringBuilder和StringBuffer来处理大量字符串拼接操作的原因,因为它们是可变的,避免了频繁的字符串对象创建。

四,字符串的比较

在Java中,字符串的比较有以下几种方式:

  1. 使用equals()方法进行比较:
String str1 = "Hello";
String str2 = "World";
boolean isEqual = str1.equals(str2);
System.out.println(isEqual);  // 输出false

equals()方法用于比较两个字符串的内容是否相等。如果相等,则返回true;否则返回false。

  1. 使用equalsIgnoreCase()方法进行比较:
String str1 = "hello";
String str2 = "Hello";
boolean isEqual = str1.equalsIgnoreCase(str2);
System.out.println(isEqual);  // 输出true

equalsIgnoreCase()方法用于比较两个字符串的内容是否相等,忽略大小写。如果相等,则返回true;否则返回false。

  1. 使用compareTo()方法进行比较:
String str1 = "Hello";
String str2 = "World";
int result = str1.compareTo(str2);
System.out.println(result);  // 输出-15

compareTo()方法用于比较两个字符串的大小关系。如果str1小于str2,则返回一个负整数;如果str1大于str2,则返回一个正整数;如果str1等于str2,则返回0。

  1. 使用compareToIgnoreCase()方法进行比较:
String str1 = "hello";
String str2 = "Hello";
int result = str1.compareToIgnoreCase(str2);
System.out.println(result);  // 输出0

compareToIgnoreCase()方法用于比较两个字符串的大小关系,忽略大小写。如果str1小于str2,则返回一个负整数;如果str1大于str2,则返回一个正整数;如果str1等于str2,则返回0。

需要注意的是,字符串的比较是基于Unicode编码的。如果需要进行基于区域设置的比较,可以使用Collator类。另外,如果需要比较字符串的前缀或后缀,可以使用startsWith()和endsWith()方法。

五,综合练习

(一)用户登录

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

以下是一个简单的Java程序,用于实现用户登录的需求:

import java.util.Scanner;

public class UserLogin {
    public static void main(String[] args) {
        // 已知的正确用户名和密码
        String correctUsername = "admin";
        String correctPassword = "123456";
        
        // 计数器,记录登录的次数
        int loginCount = 0;
        
        // 创建Scanner对象,用于接收用户输入
        Scanner scanner = new Scanner(System.in);
        
        // 循环进行登录验证,最多三次机会
        while (loginCount < 3) {
            System.out.print("请输入用户名:");
            String username = scanner.nextLine();
            
            System.out.print("请输入密码:");
            String password = scanner.nextLine();
            
            // 验证用户名和密码是否正确
            if (username.equals(correctUsername) && password.equals(correctPassword)) {
                System.out.println("登录成功!");
                break;
            } else {
                System.out.println("登录失败,请重新输入!");
                loginCount++;
            }
        }
        
        // 如果登录次数达到三次仍失败,则提示登录失败
        if (loginCount == 3) {
            System.out.println("登录失败,已达到最大尝试次数!");
        }
        
        // 关闭Scanner对象
        scanner.close();
    }
}

运行以上代码,程序会提示用户输入用户名和密码,如果输入的用户名和密码与正确的匹配,则输出"登录成功!“并结束程序。如果输入的用户名和密码不正确,则输出"登录失败,请重新输入!”,并继续循环提示用户重新输入。如果连续尝试三次后仍未成功登录,则输出"登录失败,已达到最大尝试次数!"。

(二)遍历字符串和统计字符个数

1,遍历字符串

需求:键盘录入一个字符串,使用程序实现在控制台遍历该字符串。

可以使用Java中的for循环结合字符串的charAt方法来遍历字符串。以下是一个简单的示例代码:

import java.util.Scanner;

public class TraverseString {
    public static void main(String[] args) {
        // 创建Scanner对象,用于接收用户输入
        Scanner scanner = new Scanner(System.in);
        
        // 提示用户输入字符串
        System.out.print("请输入一个字符串:");
        String input = scanner.nextLine();
        
        // 使用for循环遍历字符串
        for (int i = 0; i < input.length(); i++) {
            // 获取字符串中的每个字符并打印输出
            char c = input.charAt(i);
            System.out.println(c);
        }
        
        // 关闭Scanner对象
        scanner.close();
    }
}

运行以上代码,程序会提示用户输入一个字符串,然后使用for循环遍历该字符串,并将每个字符打印输出。

2,统计字符个数

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

可以使用Java中的字符判断方法来统计字符串中大写字母、小写字母和数字字符的个数。以下是一个示例代码:

import java.util.Scanner;

public class CountCharacters {
    public static void main(String[] args) {
        // 创建Scanner对象,用于接收用户输入
        Scanner scanner = new Scanner(System.in);
        
        // 提示用户输入字符串
        System.out.print("请输入一个字符串:");
        String input = scanner.nextLine();
        
        // 初始化大写字母、小写字母和数字字符的个数为0
        int uppercaseCount = 0;
        int lowercaseCount = 0;
        int digitCount = 0;
        
        // 遍历字符串中的每个字符
        for (int i = 0; i < input.length(); i++) {
            // 获取字符串中的每个字符
            char c = input.charAt(i);
            
            // 判断字符的类型并增加对应类型的计数
            if (Character.isUpperCase(c)) {
                uppercaseCount++;
            } else if (Character.isLowerCase(c)) {
                lowercaseCount++;
            } else if (Character.isDigit(c)) {
                digitCount++;
            }
        }
        
        // 打印统计结果
        System.out.println("大写字母个数:" + uppercaseCount);
        System.out.println("小写字母个数:" + lowercaseCount);
        System.out.println("数字个数:" + digitCount);
        
        // 关闭Scanner对象
        scanner.close();
    }
}

运行以上代码,程序会提示用户输入一个字符串,然后统计该字符串中大写字母、小写字母和数字字符的个数,并将统计结果打印输出。

(三)字符串拼接和反转

1,拼接字符串

需求:定义一个方法,把int数组中的数据按照指定格式拼接成一个字符串返回,调用该方法,并在控制台输出结果。

例如:
数组为int[] arr = {1,2,3};
执行方法后的输出结果为:[1,2,3]

要把一个整型数组按照指定格式拼接成一个字符串,可以使用字符串拼接操作符 + 将数组的元素逐个拼接到一个字符串中。

以下是一个实现该需求的示例代码:

public class ArrayToString {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3};
        String result = formatArray(arr);
        System.out.println(result);
    }

    public static String formatArray(int[] arr) {
        String result = "[";
        for (int i = 0; i < arr.length; i++) {
            result += arr[i];
            if (i != arr.length - 1) {
                result += ",";
            }
        }
        result += "]";
        return result;
    }
}

在上述代码中,我们定义了一个 formatArray 方法,该方法接收一个整型数组作为参数,并返回按照指定格式拼接后的字符串。

formatArray 方法中,我们首先定义一个名为 result 的字符串变量,初始值为 "[",表示拼接后的字符串的开始部分。

然后,我们使用 for 循环遍历整型数组 arr 中的每个元素。在循环中,我们将当前元素拼接到 result 字符串中,并在元素之后添加一个逗号(除了最后一个元素)。

最后,我们在 result 字符串末尾添加一个 "]",表示拼接后的字符串的结束部分。

main 方法中,我们创建一个整型数组 arr,并调用 formatArray 方法将其按照指定格式拼接成一个字符串。然后,我们将拼接后的字符串打印到控制台。

你可以运行该示例代码来测试不同的整型数组,看看程序是否能正确拼接成指定格式的字符串并输出。

2,字符串反转

需求:定义一个方法,实现字符串反转。
键盘录入一个字符串,调用该方法后,在控制台输出结果
例如,键盘录入abc,输出结果cba

你可以通过使用StringBuilder类的reverse()方法来实现字符串的反转。
以下是一个示例代码:

import java.util.Scanner;

public class ReverseString {
    public static void main(String[] args) {
        // 使用Scanner类获取键盘输入的字符串
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入一个字符串:");
        String input = scanner.nextLine();
        
        // 调用reverseString方法进行字符串反转
        String result = reverseString(input);
        
        // 输出反转结果
        System.out.println("反转后的字符串为:" + result);
    }
    
    public static String reverseString(String input) {
        // 创建一个StringBuilder对象,并将输入字符串逆序拼接到其中
        StringBuilder sb = new StringBuilder();
        for (int i = input.length() - 1; i >= 0; i--) {
            sb.append(input.charAt(i));
        }
        
        // 将StringBuilder转换为String类型并返回
        return sb.toString();
    }
}

运行以上代码,程序会提示你输入一个字符串,并在控制台输出反转后的字符串。例如,如果你输入abc,程序会输出cba。

(四)金额转换

需求:将数字金额转换为中文大写金额。
例如:2135 --》零佰零拾零万贰仟壹佰叁拾伍元

你可以通过编写一个方法来实现将数字金额转换为中文大写金额的功能。以下是一个示例代码:

import java.util.Scanner;

public class AmountConversion {
    // 定义中文数字
    private static final String[] CN_NUMBERS = {"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"};
    // 定义中文单位
    private static final String[] CN_UNITS = {"", "拾", "佰", "仟", "万", "拾", "佰", "仟", "亿"};

    public static void main(String[] args) {
        // 使用Scanner类获取键盘输入的数字金额
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入一个数字金额:");
        int amount = scanner.nextInt();
        
        // 调用convertAmount方法进行金额转换
        String result = convertAmount(amount);
        
        // 输出转换结果
        System.out.println("中文大写金额为:" + result + "元");
    }
    
    public static String convertAmount(int amount) {
        StringBuilder sb = new StringBuilder();
        
        // 判断是否为0
        if (amount == 0) {
            return CN_NUMBERS[0];
        }
        
        // 将金额转换为字符串
        String amountStr = String.valueOf(amount);
        
        // 反转字符串,从低位向高位遍历
        String reverseStr = new StringBuilder(amountStr).reverse().toString();
        
        // 遍历每个数字
        for (int i = 0; i < reverseStr.length(); i++) {
            int digit = Character.digit(reverseStr.charAt(i), 10);
            
            // 判断是否为0
            boolean isZero = digit == 0;
            
            // 判断是否需要添加单位
            boolean needUnit = i > 0 && !isZero && (i % 4 == 0);
            
            // 添加单位
            if (needUnit) {
                sb.append(CN_UNITS[i / 4]);
            }
            
            // 添加数字
            if (!(isZero && (i % 4 == 0) && sb.length() != 0 && sb.charAt(0) == CN_NUMBERS[0].charAt(0))) {
                sb.append(CN_NUMBERS[digit]);
            }
        }
        
        // 反转字符串得到最终结果
        return sb.reverse().toString();
    }
}

运行以上代码,程序会提示你输入一个数字金额,并在控制台输出中文大写金额。例如,如果你输入2135,程序会输出零佰零拾零万贰仟壹佰叁拾伍元。

(五)手机号屏蔽

需求:一个11位的手机号码,将第4位到第7位的数字变为 * 。
例如:13411586024 --》134****6024

你可以通过编写一个方法来实现手机号码的屏蔽功能。以下是一个示例代码:

import java.util.Scanner;

public class PhoneNumberMasking {
    public static void main(String[] args) {
        // 使用Scanner类获取键盘输入的手机号码
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入一个11位的手机号码:");
        String phoneNumber = scanner.next();
        
        // 调用maskPhoneNumber方法进行手机号码屏蔽
        String result = maskPhoneNumber(phoneNumber);
        
        // 输出屏蔽后的手机号码
        System.out.println("屏蔽后的手机号码为:" + result);
    }
    
    public static String maskPhoneNumber(String phoneNumber) {
        // 判断手机号码长度是否为11位
        if (phoneNumber.length() != 11) {
            return "手机号码长度不正确";
        }
        
        // 使用StringBuilder类来处理字符串拼接
        StringBuilder sb = new StringBuilder();
        
        // 遍历每个字符
        for (int i = 0; i < phoneNumber.length(); i++) {
            // 判断是否为需要屏蔽的位置
            if (i >= 3 && i <= 6) {
                // 将需要屏蔽的数字替换为 *
                sb.append("*");
            } else {
                // 不是需要屏蔽的位置,保留原来的字符
                sb.append(phoneNumber.charAt(i));
            }
        }
        
        // 返回屏蔽后的手机号码
        return sb.toString();
    }
}

运行以上代码,程序会提示你输入一个11位的手机号码,并在控制台输出屏蔽后的手机号码。例如,如果你输入13411586024,程序会输出134****6024。

(六)身份证信息查看

需求:用户输入一个身份证号,根据身份证号,程序输出出生年月日,性别。
例如:
人物信息为:
出生年月日:xxxx年x月x日
性别:男/女

身份证号码是中国公民身份证的唯一标识符,由18位数字和一个校验位组成。每一位数字都代表特定的含义,以下是各位的解释:

  1. 第1-2位:省、直辖市、自治区的行政区划代码。例如,11代表北京市,44代表广东省。
  2. 第3-4位:地级市、盟、自治州的行政区划代码。例如,1101代表北京市市辖区,4401代表广东省广州市。
  3. 第5-6位:县级市、县、区的行政区划代码。
  4. 第7-14位:出生年月日,按照年、月、日的顺序排列。前6位表示年份,中间2位表示月份,后面2位表示日期。
  5. 第15-17位:所在地的派出所顺序码。
  6. 第18位:校验位,用于验证身份证号码的正确性。校验位的计算方法是通过前面17位数字按照一定规则计算得出的。

通过解析身份证号码,可以获取个人的出生地、出生日期和性别等信息。

你可以通过编写一个方法来实现根据身份证号获取出生年月日和性别的功能。以下是一个示例代码:

import java.util.Scanner;

public class IDCardInfo {
    public static void main(String[] args) {
        // 使用Scanner类获取键盘输入的身份证号
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入身份证号码:");
        String idCardNumber = scanner.next();
        
        // 调用getIDCardInfo方法获取身份证信息
        String result = getIDCardInfo(idCardNumber);
        
        // 输出身份证信息
        System.out.println("人物信息为:");
        System.out.println(result);
    }
    
    public static String getIDCardInfo(String idCardNumber) {
        // 判断身份证号码长度是否合法
        if (idCardNumber.length() != 18) {
            return "身份证号码长度不正确";
        }
        
        // 获取出生年月日
        String year = idCardNumber.substring(6, 10);
        String month = idCardNumber.substring(10, 12);
        String day = idCardNumber.substring(12, 14);
        
        // 获取性别
        String genderCode = idCardNumber.substring(16, 17);
        String gender = "";
        if (Integer.parseInt(genderCode) % 2 == 0) {
            gender = "女";
        } else {
            gender = "男";
        }
        
        // 返回身份证信息
        return "出生年月日:" + year + "年" + month + "月" + day + "日" + "\n性别:" + gender;
    }
}

运行以上代码,程序会提示你输入一个身份证号码,并在控制台输出出生年月日和性别信息。例如,如果你输入身份证号码为32012319900101001X,程序会输出:

人物信息为:
出生年月日:1990年01月01日
性别:男

(七)敏感词替换

需求:用户输入的句子中有敏感词,就将敏感词替换为*。
例如:
tmd,你真的好菜 --》**,你真的好

下面是一个示例的 Java 代码,实现用户输入句子中敏感词的替换:

import java.util.Scanner;

public class SensitiveWordReplacement {
    public static void main(String[] args) {
        // 定义敏感词数组
        String[] sensitiveWords = {"tmd", "菜"};

        // 读取用户输入的句子
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入句子:");
        String sentence = scanner.nextLine();

        // 遍历敏感词数组,将句子中的敏感词替换为*
        for (String word : sensitiveWords) {
            sentence = sentence.replace(word, "*".repeat(word.length()));
        }

        // 输出替换后的句子
        System.out.println("替换后的句子:" + sentence);
    }
}

在上述代码中,我们通过定义一个字符串数组 sensitiveWords 来存储敏感词。然后使用 Scanner 类来读取用户输入的句子 sentence。接下来,通过遍历敏感词数组,使用 replace 方法将句子中的敏感词替换为相应长度的 *。最后,输出替换后的句子。

请注意,上述代码只是一个简单的示例,仅能处理敏感词为简单的字符串。如果需要更复杂的敏感词处理,可以考虑使用正则表达式或专门的自然语言处理库。

六,StringBuilder的基本操作

(一)StringBuilder概述

StringBuilder 是 Java 中的一个可变字符串类,它提供了一系列方法来操作字符串,如追加、插入、删除、替换等。与 String 类不同,StringBuilder 对象的内容可以修改,而不需要创建新的对象。

StringBuilder 类位于 java.lang 包中,是一个非线程安全的类,适用于单线程环境下的字符串拼接操作。如果在多线程环境下需要进行字符串操作,可以使用 StringBuffer 类。

以下是 StringBuilder 类的主要特点和用法:

  1. 可变性:StringBuilder 对象的内容可以被修改,可以在已有的字符串末尾追加新的字符、字符串或其他数据类型。这一特性使得 StringBuilder 在频繁字符串操作的场景下效率更高。

  2. 高效性:由于 StringBuilder 不需要创建新的字符串对象,它的字符串操作是在原对象上进行的,避免了创建新的字符串带来的性能开销。

  3. 方法:StringBuilder 类提供了一系列方法来操作字符串,如 append()insert()delete()replace() 等。可以根据具体需求选择适合的方法来进行字符串操作。

  4. 链式调用:StringBuilder 的方法通常返回自身的引用,这种设计可以支持链式调用,使得代码更简洁、易读。

下面是一个简单的示例代码,演示了 StringBuilder 的基本用法:

StringBuilder sb = new StringBuilder();
sb.append("Hello");
sb.append(" ");
sb.append("World!");
System.out.println(sb.toString()); // 输出:"Hello World!"

在上述示例中,我们先创建了一个空的 StringBuilder 对象 sb,然后使用 append() 方法依次向 sb 中追加字符串。最后,使用 toString() 方法将 StringBuilder 对象转换为普通的字符串,以便输出。

需要注意的是,由于 StringBuilder 是可变的,每次操作会在原对象上进行修改,因此在多次追加操作后,最好使用 toString() 方法将 StringBuilder 转换为普通的字符串,以避免后续的修改对结果产生影响。

(二)StringBuilder常用方法

StringBuilder 类提供了一系列常用的方法来操作字符串,以下是其中一些常用方法的简要介绍:

  1. append():向 StringBuilder 对象的末尾追加指定的字符、字符串或其他数据类型。
StringBuilder sb = new StringBuilder();
sb.append("Hello");
sb.append(" ");
sb.append("World!");
  1. insert():在 StringBuilder 对象的指定位置插入指定的字符、字符串或其他数据类型。
StringBuilder sb = new StringBuilder("Hello!");
sb.insert(5, " World");
  1. delete():删除 StringBuilder 对象中指定位置的字符或字符范围。
StringBuilder sb = new StringBuilder("Hello World!");
sb.delete(5, 11);
  1. replace():将 StringBuilder 对象中指定位置的字符或字符范围替换为指定的字符、字符串或其他数据类型。
StringBuilder sb = new StringBuilder("Hello World!");
sb.replace(6, 11, "Java");
  1. reverse():将 StringBuilder 对象中的字符顺序反转。
StringBuilder sb = new StringBuilder("Hello");
sb.reverse();
  1. length():返回 StringBuilder 对象的长度(字符数)。
StringBuilder sb = new StringBuilder("Hello");
int length = sb.length();
  1. charAt():返回 StringBuilder 对象中指定位置的字符。
StringBuilder sb = new StringBuilder("Hello");
char ch = sb.charAt(0);
  1. toString():将 StringBuilder 对象转换为普通的字符串。
StringBuilder sb = new StringBuilder("Hello");
String str = sb.toString();

需要注意的是,StringBuilder 的方法通常会在原对象上进行修改,并返回自身的引用,以支持链式调用。这意味着可以在一行代码中连续调用多个方法,如下所示:

StringBuilder sb = new StringBuilder();
sb.append("Hello").append(" ").append("World!");

上述代码连续调用了三次 append() 方法,并使用链式调用将它们连接在一起。最终的结果是 “Hello World!”。这样的链式调用既简洁又易读,可以减少代码量。

(三)练习 - 对称字符串

需求:键盘接收一个字符串,程序判断出该字符串是否是对称字符串,并在控制台打印是或不是。
对称字符串:123321、111
非对称字符串:123123

要判断一个字符串是否是对称字符串,可以使用 StringBuilder 类的 reverse() 方法将字符串反转,然后与原字符串进行比较。如果两者相等,则说明字符串是对称的。

以下是一个实现该需求的示例代码:

import java.util.Scanner;

public class SymmetricString {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入一个字符串:");
        String input = scanner.nextLine();

        StringBuilder sb = new StringBuilder(input);
        String reversed = sb.reverse().toString();

        if (input.equals(reversed)) {
            System.out.println("是对称字符串");
        } else {
            System.out.println("不是对称字符串");
        }
    }
}

在上述代码中,我们首先使用 Scanner 类从键盘接收一个字符串,并将其存储在 input 变量中。

然后,我们创建一个 StringBuilder 对象 sb,并将 input 字符串传递给它。接下来,我们调用 sbreverse() 方法将字符串反转,并使用 toString() 方法将其转换为普通的字符串 reversed

最后,我们将 inputreversed 进行比较,如果相等则打印 “是对称字符串”,否则打印 “不是对称字符串”。

你可以运行该示例代码来测试不同的输入字符串,看看程序是否能正确判断是否是对称字符串。

(四)练习 - 字符串拼接

需求:定义一个方法,把int数组中的数据按照指定格式拼接成一个字符串返回,调用该方法,并在控制台输出结果。(使用StringBuilder)

例如:
数组为int[] arr = {1,2,3};
执行方法后的输出结果为:[1,2,3]

使用 StringBuilder 类来拼接字符串,可以按照以下步骤进行:

  1. 创建一个 StringBuilder 对象。
  2. 遍历整型数组,将数组的元素逐个追加到 StringBuilder 对象中。
  3. 在每个元素的后面添加一个逗号(除了最后一个元素)。
  4. 在 StringBuilder 对象的开头添加一个左方括号 “[”,并在末尾添加一个右方括号 “]”。
  5. 调用 StringBuilder 对象的 toString() 方法将其转换为一个字符串。

以下是一个使用 StringBuilder 类实现该需求的示例代码:

public class ArrayToString {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3};
        String result = formatArray(arr);
        System.out.println(result);
    }

    public static String formatArray(int[] arr) {
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        for (int i = 0; i < arr.length; i++) {
            sb.append(arr[i]);
            if (i != arr.length - 1) {
                sb.append(",");
            }
        }
        sb.append("]");
        return sb.toString();
    }
}

在上述代码中,我们定义了一个 formatArray 方法,该方法接收一个整型数组作为参数,并返回按照指定格式拼接后的字符串。

formatArray 方法中,我们首先创建一个 StringBuilder 对象 sb,然后使用 sb.append() 方法将拼接后的字符串逐步追加到 sb 对象中。

在遍历整型数组时,我们先将左方括号 “[” 添加到 sb 对象中,然后将数组的每个元素和逗号(除了最后一个元素)追加到 sb 对象中。

最后,我们在 sb 对象末尾添加一个右方括号 “]”,并调用 sb.toString() 方法将 sb 对象转换为一个字符串,并将其作为结果返回。

main 方法中,我们创建一个整型数组 arr,并调用 formatArray 方法将其按照指定格式拼接成一个字符串。然后,我们将拼接后的字符串打印到控制台。

你可以运行该示例代码来测试不同的整型数组,看看程序是否能正确拼接成指定格式的字符串并输出。

七,StringJoiner的基本操作

(一)StringJoiner概述

StringJoiner是Java 8中新增的一个字符串拼接工具类。它提供了一种简单和灵活的方法来拼接多个字符串,并且可以自定义前缀、后缀和分隔符。

StringJoiner使用了一种类似于StringBuilder的机制来拼接字符串。您可以创建一个StringJoiner对象,并使用add()方法来添加要拼接的字符串。您还可以使用setPrefix()和setSuffix()方法来设置前缀和后缀,使用setEmptyValue()方法来设置为空时的默认值,使用setDelimiter()方法来设置分隔符。

一旦您添加了所有要拼接的字符串,您可以使用toString()方法来获取最终的拼接结果。拼接的过程是基于指定的分隔符进行的,如果没有添加任何字符串,则返回设置的空值。

StringJoiner提供了一种简洁而直观的方式来拼接字符串,尤其是当您需要动态地拼接多个字符串时。它在处理逗号分隔的字符串列表等常见场景中非常有用。

(二)StringJoiner的构造方法

StringJoiner类有三个构造方法:

  1. StringJoiner(CharSequence delimiter):使用指定的分隔符创建一个StringJoiner对象。分隔符在拼接字符串时被插入到每个元素之间。

  2. StringJoiner(CharSequence delimiter, CharSequence prefix, CharSequence suffix):使用指定的分隔符、前缀和后缀创建一个StringJoiner对象。分隔符在拼接字符串时被插入到每个元素之间,前缀和后缀则分别添加在整个拼接结果的开头和结尾。

  3. StringJoiner(CharSequence delimiter, CharSequence prefix, CharSequence suffix, CharSequence emptyValue):使用指定的分隔符、前缀、后缀和空值创建一个StringJoiner对象。分隔符在拼接字符串时被插入到每个元素之间,前缀和后缀则分别添加在整个拼接结果的开头和结尾。如果没有添加任何元素,则返回设置的空值。

这些构造方法允许您在创建StringJoiner对象时指定初始的分隔符、前缀、后缀和空值。您还可以使用相应的setter方法来修改这些属性。

(三)StringJoiner的成员方法

StringJoiner类的常用成员方法有:

  1. add(CharSequence element):将指定的元素添加到StringJoiner中。

  2. merge(StringJoiner other):将另一个StringJoiner中的元素合并到当前StringJoiner中。

  3. length():返回StringJoiner中当前拼接的字符串长度。

  4. toString():返回StringJoiner中当前拼接的字符串。

  5. setEmptyValue(CharSequence emptyValue):设置当StringJoiner中没有添加任何元素时返回的空值。

  6. setPrefix(CharSequence prefix):设置StringJoiner中拼接结果的前缀。

  7. setSuffix(CharSequence suffix):设置StringJoiner中拼接结果的后缀。

这些方法允许您向StringJoiner中添加元素、合并其他StringJoiner的元素、获取拼接结果的长度和字符串形式,以及设置空值、前缀和后缀等属性。这些方法使得使用StringJoiner类可以方便地进行字符串的拼接操作。

八,字符串的相关底层原理

(一)扩展底层原理1:字符串存储的内存原理

在Java中,字符串是不可变的(immutable)对象,即一旦创建就不能被修改。字符串的存储方式有两种:字符串常量池和堆内存。

  1. 字符串常量池:字符串常量池是一个特殊的内存区域,用于存储字符串字面量(直接使用双引号定义的字符串)。当一个字符串被创建时,如果字符串常量池中已经存在相同的字符串,则不会创建新的字符串对象,而是直接返回已存在的字符串对象的引用。这样可以节省内存空间。例如:

    String str1 = "Hello";
    String str2 = "Hello";
    

    在上面的代码中,str1和str2实际上引用的是同一个字符串对象,因为字符串常量池中已经存在"Hello"。

  2. 堆内存:除了字符串常量池,还可以使用关键字new创建字符串对象,这些对象存储在堆内存中。每次使用new创建字符串对象时,都会在堆内存中分配一块新的内存空间来存储该字符串的内容。例如:

    String str3 = new String("Hello");
    

    在上面的代码中,str3引用的是堆内存中新创建的字符串对象,而不是字符串常量池中的对象。

需要注意的是,字符串常量池和堆内存是独立的存储区域,它们存储的是不同的字符串对象。在使用字符串拼接、字符串截取等操作时,会创建新的字符串对象,而不会修改原有的字符串对象。因此,如果经常进行字符串操作,可能会产生大量的临时字符串对象,导致内存占用较高。为了解决这个问题,Java提供了StringBuffer和StringBuilder类,它们可以进行可变的字符串操作,避免了频繁创建新的字符串对象。

(二)扩展底层原理2:==号比较的到底是多少?

在Java中,==运算符用于比较两个对象的引用是否相等,即比较两个对象是否指向相同的内存地址。具体来说,==比较的是两个对象的内存地址。

当使用==比较基本数据类型时,比较的是它们的值是否相等。例如:

int num1 = 10;
int num2 = 10;
boolean result = (num1 == num2); // true

在上面的代码中,比较的是两个int类型的变量num1和num2的值。

而当使用==比较引用类型(如对象、数组等)时,比较的是两个引用变量是否指向同一个对象。例如:

String str1 = "Hello";
String str2 = "Hello";
boolean result = (str1 == str2); // true

在上面的代码中,比较的是两个String类型的引用变量str1和str2是否指向同一个字符串对象。

需要注意的是,对于字符串对象,==比较的是引用是否相等,而不是字符串的内容是否相等。如果要比较字符串的内容是否相等,应使用equals()方法。例如:

String str1 = "Hello";
String str2 = new String("Hello");
boolean result = str1.equals(str2); // true

在上面的代码中,使用equals()方法比较的是两个字符串对象的内容是否相等。

总结起来,对于基本数据类型,==比较的是值是否相等;对于引用类型,==比较的是引用是否相等。如果要比较引用类型的内容是否相等,应使用equals()方法。

(三)扩展底层原理3:字符串拼接的底层原理

在Java中,字符串拼接可以使用"+"运算符或String的concat()方法来实现。下面分别介绍这两种方式的底层原理:

  1. 使用"+“运算符进行字符串拼接:
    当使用”+"运算符拼接字符串时,编译器会将其转化为StringBuilder的append()方法调用。StringBuilder是可变的字符序列,它提供了高效的字符串拼接操作。在每次拼接时,StringBuilder会检查是否有足够的容量来存储新添加的字符,如果没有,则会自动扩容。最后,通过调用StringBuilder的toString()方法将拼接好的字符串返回。

下面是一个示例代码:

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

以上代码会被编译器转化为以下形式:

String result = new StringBuilder().append(str1).append(str2).toString();

这种方式由于使用了StringBuilder,可以避免创建大量的临时字符串对象,因此效率较高。

  1. 使用String的concat()方法进行字符串拼接:
    String的concat()方法是专门用于字符串拼接的方法,它会创建一个新的String对象来存储拼接后的字符串。在该方法内部,会先创建一个新的字符数组来保存两个字符串的字符,然后将字符数组转化为新的String对象并返回。

以下是一个示例代码:

String str1 = "Hello";
String str2 = "World";
String result = str1.concat(str2);

以上代码会创建一个新的String对象来存储拼接后的字符串。

需要注意的是,由于String对象是不可变的,每次进行字符串拼接时都会创建一个新的String对象,这可能会导致频繁的内存分配,因此在大量字符串拼接的场景下,建议使用StringBuilder或StringBuffer来提高性能。

(四)扩展底层原理4:StringBuilder提高效率原理图

StringBuilder是一个可变的字符序列,它内部使用一个字符数组来存储字符串的内容。当我们使用StringBuilder进行字符串拼接时,它会在内部进行如下操作:

  1. 初始状态下,StringBuilder会创建一个默认大小的字符数组,并用它来存储字符串的内容。

  2. 当我们调用append()方法添加字符串时,StringBuilder会检查数组的容量是否足够。如果足够,直接将新的字符串添加到数组末尾,并更新数组的长度。

  3. 如果数组的容量不足,StringBuilder会进行自动扩容。它会创建一个新的更大的字符数组,并将原来数组中的内容复制到新数组中。

  4. 在每次拼接操作之后,StringBuilder会记录当前字符串的长度,以便后续的拼接操作可以直接在当前长度的基础上进行。

  5. 最后,当我们调用toString()方法时,StringBuilder会根据当前的字符串长度创建一个新的String对象,并将字符数组中的内容复制到新的String对象中。

通过以上的操作,StringBuilder可以避免创建大量的临时字符串对象,从而提高字符串拼接的效率。它只需要对字符数组进行操作,而不需要频繁地创建和销毁String对象,减少了内存分配和垃圾回收的开销。

需要注意的是,StringBuilder是非线程安全的,如果在多线程环境下使用,应该使用线程安全的StringBuffer类来替代。StringBuffer的原理与StringBuilder类似,但它的方法都被synchronized修饰,可以保证对字符串的操作是线程安全的。

(五)扩展底层原理5:StringBuilder代码分析

以下是一个简单示例的Java StringBuilder代码:

StringBuilder sb = new StringBuilder();
sb.append("Hello");
sb.append(" World");
sb.append("!");
String result = sb.toString();
System.out.println(result);

这段代码创建了一个StringBuilder对象,并使用append()方法将三个字符串拼接到一起。最后,通过调用toString()方法将拼接后的字符串转换为一个普通的String对象,并将其打印出来。

在分析这段代码之前,我们先来了解一下StringBuilder的常用方法:

  • append(String str):将给定的字符串追加到当前StringBuilder对象的末尾。
  • toString():将当前StringBuilder对象的内容转换为一个字符串对象。
  • 每次调用append()方法后,StringBuilder对象的长度会增加,而数组的容量可能会发生变化。

现在来分析上述代码的执行过程:

  1. 在创建StringBuilder对象时,它会使用默认的初始容量(16)创建一个字符数组,用于存储字符串的内容。

  2. 第一个append()方法调用将"Hello"字符串追加到StringBuilder对象的末尾。由于初始容量足够大,所以直接将字符串添加到数组中,并更新长度。此时,StringBuilder对象的内容为"Hello"。

  3. 第二个append()方法调用将" World"字符串追加到StringBuilder对象的末尾。由于容量不足,StringBuilder会自动扩容,创建一个新的更大的字符数组,并将原来数组中的内容复制到新数组中。此时,StringBuilder对象的内容为"Hello World"。

  4. 第三个append()方法调用将"!“字符串追加到StringBuilder对象的末尾。由于容量仍然足够,所以直接将字符串添加到数组中,并更新长度。此时,StringBuilder对象的内容为"Hello World!”。

  5. 最后,通过调用toString()方法将StringBuilder对象的内容转换为一个新的String对象。此时,StringBuilder对象的内容不再改变。将拼接后的字符串赋值给result变量,并打印出来。输出结果为"Hello World!"。

通过使用StringBuilder,我们可以避免创建临时的字符串对象,提高字符串拼接的效率。同时,StringBuilder还提供了其他常用的方法,如insert()、delete()、replace()等,用于对字符串进行插入、删除、替换等操作。在实际开发中,可以根据需求选择合适的方法来进行字符串的处理。

九,综合练习

(一)阿拉伯数字转换罗马数字

需求:键盘录入一个字符串
要求1:长度为小于等于9
要求2:只能是数字
将内容变为罗马数字
下面是阿拉伯数字跟罗马数字的对应关系
1 -> I
2 -> II
3 -> III
4 -> IV
5 -> V
6 -> VI
7 -> VII
8 -> VIII
9 -> IX

注意:罗马数字里面没有0的,如果键盘录入的数字包含0,可以变成“ ”(长度为0的字符串)。

可以使用Java的字符数组和字符串拼接的方法来实现阿拉伯数字转换为罗马数字的功能。下面是一个示例代码:

import java.util.Scanner;

public class ArabicToRoman {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入一个小于等于9的数字: ");
        String input = scanner.nextLine();

        if (input.length() > 9) {
            System.out.println("输入的数字长度超过了9,请重新输入。");
            return;
        }

        if (!input.matches("[1-9]+")) {
            System.out.println("输入的不是有效的数字,请重新输入。");
            return;
        }

        String[] romanNumerals = {"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"};

        StringBuilder result = new StringBuilder();
        for (int i = 0; i < input.length(); i++) {
            int digit = Character.getNumericValue(input.charAt(i));
            result.append(romanNumerals[digit]);
        }

        System.out.println("转换后的罗马数字为: " + result.toString());
    }
}

该示例代码中,首先使用Scanner类从键盘获取用户输入的数字字符串。然后检查输入的字符串长度是否大于9或是否包含除1~9之外的字符,如果不满足要求,则给出相应的提示并结束程序。如果输入的字符串满足要求,就通过循环遍历字符串的每个字符,并根据字符的数值获取对应的罗马数字,并将其拼接到结果字符串中。最后,输出转换后的罗马数字。

请注意,该示例代码没有处理输入包含0的情况,根据你的需求,可以将数字0转换为空字符串或其他字符,例如将 romanNumerals[0] 设置为" "。你可以根据具体需求做相应的修改。

(二)调整字符串的内容并比较

需求:给定两个字符串,A和B
A的旋转操作就是将A最左边的字符移动到最右边。
例如,若A=‘abcde’,在移动一次之后结果就是’bcdea’。
如果在若干次调整之后,A能变成B,那么返回True。
如果不能匹配成功,则返回false。

可以使用Java的字符串操作方法来实现旋转字符串的功能,并进行比较。下面是一个示例代码:

public class RotateString {
    public static boolean isRotateString(String A, String B) {
        if (A.length() != B.length()) {
            return false;
        }

        String rotatedString = A;
        for (int i = 0; i < A.length(); i++) {
            rotatedString = rotateOnce(rotatedString);
            if (rotatedString.equals(B)) {
                return true;
            }
        }

        return false;
    }

    private static String rotateOnce(String str) {
        return str.substring(1) + str.charAt(0);
    }

    public static void main(String[] args) {
        String A = "abcde";
        String B = "cdeab";

        boolean result = isRotateString(A, B);
        System.out.println("A可以通过旋转变为B: " + result);
    }
}

在该示例代码中,首先判断字符串A和B的长度是否相等,如果不相等,则直接返回false。然后,初始化旋转后的字符串为A,并进行循环遍历,每次循环将旋转后的字符串按照旋转一次的规则进行调整。旋转一次的规则是将字符串的第一个字符移动到最后,并将剩下的字符按照原顺序拼接。在每次旋转后,判断旋转后的字符串是否与B相等,如果相等则返回true。如果循环结束后仍然没有找到相等的字符串,则返回false。

在main方法中,示例代码给出了一个示例输入,字符串A为’abcde’,字符串B为’cdeab’。程序会输出A是否可以通过旋转变为B的结果。

你可以根据需要修改示例代码以适应更多的测试案例。

(三)打乱字符串内容

需求:键盘输入任意字符串,打乱里面的内容。

可以使用Java的字符串操作方法和随机数生成来实现打乱字符串的功能。下面是一个示例代码:

import java.util.Scanner;
import java.util.Random;

public class ShuffleString {
    public static String shuffleString(String str) {
        char[] charArray = str.toCharArray();
        Random random = new Random();

        for (int i = 0; i < charArray.length; i++) {
            int j = random.nextInt(charArray.length);
            char temp = charArray[i];
            charArray[i] = charArray[j];
            charArray[j] = temp;
        }

        return new String(charArray);
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入一个字符串:");
        String inputString = scanner.nextLine();

        String shuffledString = shuffleString(inputString);
        System.out.println("打乱后的字符串:" + shuffledString);
    }
}

在该示例代码中,首先使用Scanner类从键盘输入要打乱的字符串。然后,使用toCharArray()方法将字符串转换为字符数组,这样我们可以通过数组索引来交换字符的位置。接下来,创建一个Random对象来生成随机数。通过随机数生成的索引,将字符数组中的字符进行交换,从而实现打乱字符的目的。最后,使用new String(charArray)将打乱后的字符数组转换回字符串,并输出结果。

在示例代码中,键盘输入的字符串为变量inputString。程序会打乱字符串的内容,并输出打乱后的结果。

(四)生成验证码

需求:内容可以是小写字母,也可以是大写字母,还可以是数字。
规则:长度为5,内容是由4位字母和1位数字组成。其中数字只有1位,但是可以出现在任意位置。

可以使用Java的字符串操作方法和随机数生成来生成验证码。下面是一个示例代码:

import java.util.Random;

public class CaptchaGenerator {
    public static String generateCaptcha() {
        String lowercaseLetters = "abcdefghijklmnopqrstuvwxyz";
        String uppercaseLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        String numbers = "0123456789";
        Random random = new Random();
        StringBuilder sb = new StringBuilder();

        // 生成4位字母
        for (int i = 0; i < 4; i++) {
            int randomIndex = random.nextInt(lowercaseLetters.length());
            char randomChar = lowercaseLetters.charAt(randomIndex);
            sb.append(randomChar);
        }

        // 生成数字
        int randomNumberIndex = random.nextInt(numbers.length());
        char randomNumber = numbers.charAt(randomNumberIndex);
        sb.insert(random.nextInt(5), randomNumber);

        return sb.toString();
    }

    public static void main(String[] args) {
        String captcha = generateCaptcha();
        System.out.println("生成的验证码:" + captcha);
    }
}

在示例代码中,首先定义了包含小写字母、大写字母和数字的字符串。然后,使用Random类生成随机数,并根据规则随机生成4位字母和1位数字。通过StringBuilder类来构建最终的验证码。在生成数字时,使用insert方法将数字插入到0到4之间的随机位置。

示例代码中的main方法调用generateCaptcha函数来生成验证码,并将其输出。

(五)计算两数乘积

需求:给定两个以字符串形式表示的非负整数num1和num2,返回num1和num2的乘积,它们的乘积也表示为字符串形式。

可以使用Java的字符串操作方法和数学运算来实现两个字符串形式的非负整数的乘法。下面是一个示例代码:

public class MultiplyStrings {
    public static String multiply(String num1, String num2) {
        int m = num1.length();
        int n = num2.length();
        int[] result = new int[m + n];

        for (int i = m - 1; i >= 0; i--) {
            for (int j = n - 1; j >= 0; j--) {
                int multiply = (num1.charAt(i) - '0') * (num2.charAt(j) - '0');
                int p1 = i + j;
                int p2 = i + j + 1;
                int sum = multiply + result[p2];

                result[p1] += sum / 10;
                result[p2] = sum % 10;
            }
        }

        StringBuilder sb = new StringBuilder();
        for (int digit : result) {
            if (sb.length() != 0 || digit != 0) {
                sb.append(digit);
            }
        }

        return sb.length() == 0 ? "0" : sb.toString();
    }

    public static void main(String[] args) {
        String num1 = "123";
        String num2 = "456";
        String product = multiply(num1, num2);
        System.out.println("乘积:" + product);
    }
}

在示例代码中,首先获取两个字符串的长度,并创建一个数组来保存乘法结果。然后,使用两个嵌套的循环来遍历两个字符串的每一位数字,并进行乘法运算。乘法结果存储在数组中的对应位置。

在乘法运算过程中,需要注意进位的处理。将乘法结果的个位数存储在p2位置,十位数存储在p1位置。如果p2位置原本已经有值,需要将乘法结果加上p2位置的值。然后,将进位部分加到p1位置。

最后,使用StringBuilder类来构建最终的乘积结果字符串。需要注意的是,如果乘积结果为0,则返回字符串"0"。

示例代码中的main方法调用multiply函数来计算两个字符串形式非负整数的乘积,并将其输出。

你可能感兴趣的:(Java,复习笔记,java,笔记,字符串,String)