我正在做的是:
String myName = "domanokz";
myName.charAt(4) = 'x';
这给出了错误。有什么方法可以做到吗?
#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
实例是不可变的。无论您是否需要线程安全,StringBuffer
和StringBuilder
都是可变的,并且适合于此目的。它可以被视为作弊:您可以使用反射来修改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
评论
我意识到这已经死了,但是值得注意的是,它永远不允许在Java中分配函数调用的结果。没有诸如C(?)和C ++的引用。VB中的@ValekHalfHeart,您使用括号访问数组的索引,这可能是为什么我从Java启动时感到困惑的原因:D
@ApproachingDarknessFish我不确定您的意思是“禁止在Java中分配函数调用的结果”。当然可以加倍r = Math.sin(3.14)?它与这个问题有什么关系?谢谢。
@ flow2k哎呀,老评论,所以我不能编辑,但这是一个错字,它应该说“绝不允许将其赋给Java中的函数调用结果”。即您可以编写“ foo = bar();”但绝不会“ bar()= foo;”。
感谢您对@ApproachingDarknessFish的澄清。我认为为函数的结果分配某些东西会很奇怪-是否有实际上允许这样做的语言?我不知道用例会是什么。