字符串替换方法不替换字符


79

我有一个以字符串形式传递的句子,我正在对单词“ and”进行替换,我想用“”替换它。并且它不是用空格替换“和”一词。以下是我的逻辑示例。而且,当我调试该逻辑时,它的逻辑确实落入了句子。

String sentence = "Define, Measure, Analyze, Design and Verify"
if (sentence.contains("and")){
    sentence.replace("and", " ");
}

这里有我想念的东西吗?


33
字符串是不可变的。
马特·鲍尔

Answers:


171

而且,当我调试该逻辑时,它的逻辑确实落入了句子。

是的,然后您放弃返回值。

Java中的字符串是不可变的-当您调用时replace,它不会更改现有字符串的内容-它会返回经过修改的字符串。所以你要:

sentence = sentence.replace("and", " ");

这适用于所有的字符串(方法substringtoLowerCase等等)。它们都不更改字符串的内容。

请注意,您实际上并不需要在某种情况下执行此操作-毕竟,如果该句子包含"and",执行替换也不会造成损害:

String sentence = "Define, Measure, Analyze, Design and Verify";
sentence = sentence.replace("and", " ");

2
我得叫你回答一个重复,而不是投票关闭。之前已经问过这个问题很多次了-乔恩,怎么了?
马特·鲍尔

2
@MattBall IHMO
MadProgrammer

20
@MattBall:我经常发现,给出一个完整的完整答案要比找到一个具有良好答案的重复副本更快。我相信(在某种程度上是自负的),我的回答要比您发现的重复回答中被接受的回答要好,这甚至根本没有技术意义。(“您需要使您的字符串实际上等于您对字符串所做的更改”-什么?)另外,我想指出有关无需首先检查收容条件的方面。
乔恩·斯基特

有时间考虑一下,我觉得这是一个更好的答案。
yms 2015年

68

字符串是不可变的,这意味着它们的内容不能更改。调用时,replace(this,that)您将得到一个全新的String。如果要保留此新副本,则需要将其分配给变量。您可以覆盖旧参考(lasentence = sentence.replace(this,that)或新参考,如下所示:

public class Test{

    public static void main(String[] args) {

        String sentence = "Define, Measure, Analyze, Design and Verify";

        String replaced = sentence.replace("and", "");
        System.out.println(replaced);

    }
}

顺便说一句,请注意,我已经删除了contains()这张支票,因为这是不必要的呼叫。如果不包含它,替换将无法进行任何替换。如果您要替换的内容与要检查的实际条件不同,则只希望包含该方法。


41
这个答案的文字暗示contains()是引起问题的电话-并非如此。这是不必要的电话,但实际上并没有引起任何问题。问题是由于忽略的返回值replace,答案中根本没有解释。
乔恩·斯基特

@Jon Skeet先生,我真的很抱歉,如果答案中的文字暗示了其他方式……但是当我说不需要时,我表示那是不必要的....好的,我会在回答中包括它更明显.....
Kumar Vivek Mitra

如果这样做会更好吗sentence.replace(" and", ",");
Khaled.K 2014年

@JonSkeet和其他人-我添加了一个段落,该段落实际上解释了所发生的情况,并将误导性文本移到末尾,因为它与当前的实际问题相当多余。
corsiKa 2014年

3
@corsiKa:说实话,我不会做为其他人对现有答案的编辑。它极大地改变了答案的含义。
乔恩·斯基特

9

您对返回值没做任何事情replace。您需要分配方法的结果,这是新的String

sentence = sentence.replace("and", " ");

String在Java中A是不可变的。像replace返回新方法之类的方法String

您的contains测试是不必要的:replace如果没有要替换的文本实例,则只需不操作即可。


我的包含逻辑是必需的,因为在某些情况下,我不想替换它。逻辑并不完全像这样,我只是以此为例。
Yams 2012年

@MarkBasler:您提供的示例不需要包含逻辑,因此您不应该包含它。好的问题应该只包含显示问题所需要的内容-通过包含在您提供的情况下毫无意义的代码,您使问题更加分散。
乔恩·斯基特

我担心容器,我担心替换。
yms 2012年

顺便说一句,您将其标记为重复并回答。保持优雅。
Yams 2014年

嗨@MarkBasler:我正在尝试提供帮助。我认为这两个动作没有冲突:您的问题是一个非常常见的问题,经常出现:Java字符串是不可变的。当我将一个问题标记为重复时,我试图在此处提高问题和答案的质量,但与此同时,为了留下针对您问题的答案,我希望为您提供针对您的示例的更多即时帮助。您可能会发现此问题对meta有用。
pb2q 2014年

8

您应该重新分配替换结果,如下所示:

 sentence = sentence.replace("and", " ");

请注意,String该类是不可变的,这意味着其所有方法都返回一个新字符串,并且永远不会就地修改原始字符串,因此String必须将实例中的方法调用的结果分配给变量或立即用于更改生效。


字符串应该是不可变的,但是String库存在一些错误,可让您修改原始字符串。
yams 2012年

4
@MarkBasler:嗯,您到底在说什么错误?而且,如果您知道字符串是不可变的,则不清楚为什么您希望代码完全起作用……
Jon Skeet 2012年

-1
package com.tulu.ds;

public class EmailSecurity {
    public static void main(String[] args) {
        System.out.println(returnSecuredEmailID("sample717@gmail.com"));
    }
    private static String returnSecuredEmailID(String email){
        String str=email.substring(1, email.lastIndexOf("@")-1);
        return email.replaceAll(email.substring(1, email.lastIndexOf("@")-1),replacewith(str.length(),"*"));
    }
    private static String replacewith(int length,String replace) {
        String finalStr="";
        for(int i=0;i<length;i++){
            finalStr+=replace;
        }
        return finalStr;
    }   
}

3
请不要只写代码答案,而要解释您的代码如何解决OP的问题。From Review
abccd
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.