我正在尝试替换字符串中特定索引处的字符。

我正在做的是:

String myName = "domanokz";
myName.charAt(4) = 'x';


这给出了错误。有什么方法可以做到吗?

评论

我意识到这已经死了,但是值得注意的是,它永远不允许在Java中分配函数调用的结果。没有诸如C(?)和C ++的引用。

VB中的@ValekHalfHeart,您使用括号访问数组的索引,这可能是为什么我从Java启动时感到困惑的原因:D

@ApproachingDarknessFish我不确定您的意思是“禁止在Java中分配函数调用的结果”。当然可以加倍r = Math.sin(3.14)?它与这个问题有什么关系?谢谢。

@ flow2k哎呀,老评论,所以我不能编辑,但这是一个错字,它应该说“绝不允许将其赋给Java中的函数调用结果”。即您可以编写“ foo = bar();”但绝不会“ bar()= foo;”。

感谢您对@ApproachingDarknessFish的澄清。我认为为函数的结果分配某些东西会很奇怪-是否有实际上允许这样做的语言?我不知道用例会是什么。

#1 楼

字符串在Java中是不可变的。您无法更改它们。

您需要创建一个替换了字符的新字符串。

String myName = "domanokz";
String newName = myName.substring(0,4)+'x'+myName.substring(5);


也可以使用StringBuilder :

StringBuilder myName = new StringBuilder("domanokz");
myName.setCharAt(4, 'x');

System.out.println(myName);


评论


嗯,您的意思是像replace方法那样,它不会修改字符串,而只会返回一个新字符串?

–dpp
2011年8月5日下午6:39

佩塔尔先生,​​这有点复杂。那是最好的方式吗?啊,我以前听说过StringBuilder,这有什么区别吗?会给我一个更简单的方法吗?

–dpp
2011年8月5日在6:41



#2 楼

将String变成char [],用索引替换字母,然后将数组转换回String。

String myName = "domanokz";
char[] myNameChars = myName.toCharArray();
myNameChars[4] = 'x';
myName = String.valueOf(myNameChars);


评论


喜欢这个解决方案。我最终将第三行更改为myNameChars [index] = character.toCharArray()[0];为了简化。不错的解决方案。

–戴尔
17年1月1日在21:22

它看起来比另一个丑陋的myName.substring(0,4)+'x'+ myName.substring(5)好得多;

–user924
18年11月4日在14:31

它要简单得多

– Shiva Acharjee
3月14日14:12

请记住,这会将字符串复制两次。相反,使用String串联版本可能更快。

– Ariel
11月11日在1:46

#3 楼

String是Java中的不可变类。任何似乎对其进行修改的方法总是会返回带有修改的新字符串对象。

#4 楼

我同意Petar Ivanov的观点,但最好采用以下方式实施:

public String replace(String str, int index, char replace){     
    if(str==null){
        return str;
    }else if(index<0 || index>=str.length()){
        return str;
    }
    char[] chars = str.toCharArray();
    chars[index] = replace;
    return String.valueOf(chars);       
}


评论


是什么使您的解决方案更好?

–dpp
2012年5月3日,下午1:43

#5 楼

您可以覆盖字符串,如下所示:

String myName = "halftime";
myName = myName.substring(0,4)+'x'+myName.substring(5);  


请注意,字符串myName出现在两行以及第二行的两侧。

因此,即使从技术上讲字符串可能是不可变的,但实际上,您可以通过覆盖它们将它们视为可编辑的。

评论


我没有拒绝您的回答,但我必须承认“覆盖”一词有问题(尽管我认为我们同意后面的概念)。对象本身保持不变。您只需使变量引用另一个对象即可。顺便说一句,有趣的是您在示例中至少创建了四个String实例。

– C.香槟
2015年10月20日,12:47

#6 楼

如此处先前的回答,String实例是不可变的。无论您是否需要线程安全,StringBufferStringBuilder都是可变的,并且适合于此目的。它可以被视为作弊:您可以使用反射来修改String对象包含的内部char数组。反射允许您访问通常隐藏在当前作用域中的字段和方法(私有方法或其他类的字段...)。

public static void main(String[] args) {
    String text = "This is a test";
    try {
        //String.value is the array of char (char[])
        //that contains the text of the String
        Field valueField = String.class.getDeclaredField("value");
        //String.value is a private variable so it must be set as accessible 
        //to read and/or to modify its value
        valueField.setAccessible(true);
        //now we get the array the String instance is actually using
        char[] value = (char[])valueField.get(text);
        //The 13rd character is the "s" of the word "Test"
        value[12]='x';
        //We display the string which should be "This is a text"
        System.out.println(text);
    } catch (NoSuchFieldException | SecurityException e) {
        e.printStackTrace();
    } catch (IllegalArgumentException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    }
}


#7 楼

我应该注意到的第一件事是charAt是一种方法,使用等号为其赋值将不会执行任何操作。如果字符串是不可变的,则对字符串对象进行更改的charAt方法必须接收包含新字符的参数。不幸的是,字符串是不可变的。要修改字符串,我需要使用Petar Ivanov先生建议的StringBuilder。

#8 楼

这将起作用

   String myName="domanokz";
   String p=myName.replace(myName.charAt(4),'x');
   System.out.println(p);


输出:domaxokz

评论


尽管我强烈反对这种在StackOverFlow网站上允许他人“编辑”工作的方法。完全不公平:/

–地狱D
2012年8月23日在16:39

语法错误。即使更正,例如我想用“ x”替换第一个“ o”,第二个“ o”也将替换。

–dpp
2012年9月7日在4:46



这将替换所有与charAt 4相同的字符。

–Shripad Bhat
2015年8月8日13:10

问题:myName.replace(myName.charAt(5),'x')将给您dxmanxkz,可能不是必需的。

–达伍德·伊本·卡里姆(Dawood ibn Kareem)
17年1月29日在6:35