为何最后sysout未显示字符串变更?字符串指定字符删除排查
问题分析与修复方案
嘿,我一眼就看出你代码里的核心问题了——Java中的String是不可变类型!你在decal方法里折腾了半天,其实根本没碰着原字符串的一根毫毛,更别说修改它了。咱们一步步拆解问题,再给你把代码改对。
为什么原字符串没变化?
- String的不可变性:Java里的String对象一旦创建,内部的字符数组就不能被修改。你在
decal里写的char a = A.charAt(i); a = A.charAt(i+1);,只是把局部变量a的值改了,和传入的A字符串半毛钱关系都没有。最后给e赋值'\0'也是同理,只是改了局部变量,原字符串纹丝不动。 decal方法逻辑无效:就算String是可变的,你当前的逻辑也做不到“删除字符”——你只是把局部变量的值替换了,根本没把新的值写回字符串里。
修复方案(两种常用方式)
方案1:用StringBuilder实现(推荐,效率更高)
StringBuilder是可变的字符序列,专门用来做字符串的修改操作。咱们把代码改成这样:
import java.util.Scanner; public class Main { // 优化查找方法:没找到字符返回-1,比返回字符串长度更直观 public static int search(String ch, char x) { for (int i = 0; i < ch.length(); i++) { if (ch.charAt(i) == x) { return i; } } return -1; } // 改成操作StringBuilder,直接删除指定位置的字符 public static void decal(int x, StringBuilder sb) { if (x >= 0 && x < sb.length()) { sb.deleteCharAt(x); } } public static void main(String[] args) { System.out.println("donner une chaine"); Scanner sc = new Scanner(System.in); String name = sc.nextLine(); System.out.println("donner un caractere"); char w = sc.next().charAt(0); int val = search(name, w); if (val == -1) { System.out.println("le caractere " + w + " n'est pas present dans la chaine"); } else { System.out.println("la position de la lettre " + w + " est " + val); // 把String转成可变的StringBuilder StringBuilder sbName = new StringBuilder(name); decal(val, sbName); // 再转成String赋值回name name = sbName.toString(); } sc.close(); System.out.println(name); } }
方案2:用字符串截取实现(简单直接)
如果不想用StringBuilder,也可以直接通过字符串截取来拼接出新的字符串,跳过要删除的字符:
在main方法里找到val后,替换这段代码:
if (val != -1) { // 截取目标位置之前的部分 + 目标位置之后的部分 name = name.substring(0, val) + name.substring(val + 1); }
这种方法写起来简单,但每次拼接都会创建新的String对象,字符串较长时效率不如StringBuilder。
额外优化细节
- 原
search方法没找到字符时返回字符串长度,这时候如果传入decal会导致循环越界,改成返回-1更安全,也方便判断字符是否存在。 - 加入了字符不存在的判断逻辑,避免无效操作,用户体验也更好。
内容的提问来源于stack exchange,提问作者Mohamed Belkamel
相关产品推荐
相关产品推荐

