【问题标题】:Replace a character at a specific index in a string?替换字符串中特定索引处的字符?
【发布时间】:2011-10-20 14:37:39
【问题描述】:

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

我正在做的是:

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

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

【问题讨论】:

  • 我意识到这已经被回答到死了,但值得注意的是,从不允许在 java 中分配函数调用的结果。没有 C(?) 和 C++ 的引用之类的东西。
  • @ValekHalfHeart 在VB中,你使用括号来访问数组的索引,这可能是我开始使用Java时感到困惑的原因:D
  • @ApproachingDarknessFish 我不确定您所说的“永远不允许在 java 中分配函数调用的结果”是什么意思。你当然可以double r = Math.sin(3.14)?它与这个问题有什么关系?谢谢。
  • @flow2k 哦,天哪,老评论,所以我无法编辑,但这是一个错字,应该说“永远不允许分配 to Java 中函数调用的结果”。 IE。你可以写“foo = bar();”但绝不是“bar() = foo;”。
  • 感谢@ApproachingDarknessFish 的澄清。我认为将某些东西分配给函数的结果会很奇怪-是否有语言实际上允许这样做?我想知道用例是什么。

标签: java string replace indexing character


【解决方案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 方法,它不会修改字符串,只会返回一个新字符串?
  • Petar 先生有点复杂。这是你最好的方法吗?啊,我以前听说过StringBuilder,那有什么区别吗?它会给我一个更简单的方法吗?
【解决方案2】:

将字符串转换为char[],用索引替换字母,然后将数组转换回字符串。

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

【讨论】:

  • 喜欢这个解决方案。我最终将第三行更改为 myNameChars[index] = character.toCharArray()[0];为了简化。很好的解决方案。
  • 它看起来比另一个丑多了myName.substring(0,4)+'x'+myName.substring(5);
  • 请记住,这会将字符串复制两次。改用字符串连接版本可能会更快。
【解决方案3】:

String 是 java 中的不可变类。任何似乎修改它的方法总是返回一个带有修改的新字符串对象。

如果您想操作字符串,请考虑使用StringBuilderStringBuffer,以防您需要线程安全。

【讨论】:

    【解决方案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);       
    }
    

    【讨论】:

    • 什么使您的解决方案更好?
    • 它处理意外的值。像null 字符串和越界索引。
    【解决方案5】:

    正如之前在此回答的,String 实例是不可变的StringBufferStringBuilder 是可变的,无论您是否需要线程安全,都适用于这样的目的。

    但是有一种方法可以修改字符串,但我绝不会推荐它,因为它不安全、不可靠并且可以被视为作弊:您可以使用 reflection 修改内部的 char 数组 String 对象包含。 Reflection 允许您访问通常隐藏在当前范围内的字段和方法(私有方法或来自另一个类的字段...)。

    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();
        }
    }
    

    【讨论】:

      【解决方案6】:

      你可以覆盖一个字符串,如下:

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

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

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

      【讨论】:

      • 我没有否决您的回答,但我必须承认我对“覆盖”一词有疑问(尽管我认为我们同意背后的概念)。对象本身保持不变。你只是让你的变量引用另一个对象。顺便提一下,您在示例中至少创建了四个 String 实例。
      【解决方案7】:

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

      【讨论】:

        【解决方案8】:

        你可以像这样覆盖相同的字符串

        String myName = "domanokz";
        myName = myName.substring(0, index) + replacement + myName.substring(index+1); 
        

        其中 index = 要替换的 char 的索引。 index+1 添加字符串的其余部分

        【讨论】:

          【解决方案9】:

          这会起作用

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

          输出:domaxokz

          【讨论】:

          • 虽然我强烈反对这种被允许在 StackOverFlow 网站上“编辑”他人工作的方法。完全不公平:/
          • 语法错误。即使更正了,假设我想用 'x' 替换第一个 'o',第二个 'o' 也会被替换。
          • 这将替换所有与 charAt 4 相同的字符。
          • 问题:myName.replace(myName.charAt(5),'x') 会给你dxmanxkz,这可能不是我们需要的。
          • 它会给你“dxmanokz”作为替换只替换第一次出现,除非它是一个正则表达式。不过,出于同样的原因,仍然不正确。
          猜你喜欢
          • 1970-01-01
          • 2017-01-14
          • 2012-06-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-08-09
          相关资源
          最近更新 更多