【问题标题】:How to insert a character in a string at a certain position?如何在字符串中的某个位置插入一个字符?
【发布时间】:2011-08-18 13:36:48
【问题描述】:

我收到了一个 6 位数的 int。我想将其显示为String,在int 末尾的 2 位处带有小数点 (.)。我想使用float,但建议使用String 以获得更好的显示输出(而不是1234.5 将是1234.50)。因此,我需要一个将int 作为参数并返回格式正确的String 的函数,小数点距离末尾2 位。

说:

int j= 123456 
Integer.toString(j); 

//processing...

//output : 1234.56

【问题讨论】:

  • String str = Integer.toString(j); //integer or string with white spaces<br/> str = new StringBuffer(str.trim()).insert(str.length()-2, ".").toString();

标签: java string casting


【解决方案1】:

如 cmets 中所述,StringBuilder 可能比使用 StringBuffer 更快。如 Java 文档中所述:

该类提供与 StringBuffer 兼容的 API,但不保证同步。此类设计用于在单个线程正在使用字符串缓冲区的地方(通常情况下)用作 StringBuffer 的替代品。在可能的情况下,建议优先使用此类而不是 StringBuffer,因为它在大多数实现下会更快。

用法:

String str = Integer.toString(j);
str = new StringBuilder(str).insert(str.length()-2, ".").toString();

或者如果您需要同步,请使用类似用法的StringBuffer

String str = Integer.toString(j);
str = new StringBuffer(str).insert(str.length()-2, ".").toString();

【讨论】:

  • 此解决方案适用于任何 >= 4 个字符的字符串:字符串“111”给了我“.111”,任何小于这个值的结果都会导致 java.lang.StringIndexOutOfBoundsException(尝试访问不'不存在)。
【解决方案2】:
int j = 123456;
String x = Integer.toString(j);
x = x.substring(0, 4) + "." + x.substring(4, x.length());

【讨论】:

  • 字符串是不可变的。虽然这可行,但使用 StringBuilder 之类的东西在道德上是正确的,更不用说会让你的代码更快了。
  • 忘记 StringBuilder。使用这样的格式,String.format 是最好的选择。
  • 没有循环,这是一个简单的串联情况,编译器应该使用字符串生成器对其进行优化,为了便于阅读,我更喜欢使用 + 运算符,在这种情况下不需要显式使用 StringBuilder。使用“StringBuilder”解决方案,因为它更快不尊重优化规则。代码可读性。分析后优化,仅在需要的地方进行优化。 en.wikipedia.org/wiki/Program_optimization#Quotes
  • 第二个子字符串调用不需要 x.length()。
  • 当数字是不同的位数时,此解决方案将失败。对于 12345,它将输出 1234.5,对于 1234567,它将输出 1234.567。如果您总是希望最后 2 位在小数点后,请确保该数字至少有 3 位,然后执行 x = x.substring(0, x.length()-2) + "." + x.substring(x.length()-2);
【解决方案3】:
int yourInteger = 123450;
String s = String.format("%6.2f", yourInteger / 100.0);
System.out.println(s);

【讨论】:

  • 我建议使用java.math.BigDecimal,因为使用double 会导致rounding error。如果速度比精度更有价值double 更好。
【解决方案4】:

使用 ApacheCommons3 StringUtils,你也可以这样做

int j = 123456;
String s = Integer.toString(j);
int pos = s.length()-2;

s = StringUtils.overlay(s,".", pos, pos);

它基本上是子字符串连接,但如果你不介意使用库,或者已经依赖于 StringUtils,它会更短

【讨论】:

    【解决方案5】:

    在大多数用例中,使用StringBuilder(如已回答)是一种很好的方法。但是,如果性能很重要,这可能是一个不错的选择。

    /**
     * Insert the 'insert' String at the index 'position' into the 'target' String.
     * 
     * ````
     * insertAt("AC", 0, "") -> "AC"
     * insertAt("AC", 1, "xxx") -> "AxxxC"
     * insertAt("AB", 2, "C") -> "ABC
     * ````
     */
    public static String insertAt(final String target, final int position, final String insert) {
        final int targetLen = target.length();
        if (position < 0 || position > targetLen) {
            throw new IllegalArgumentException("position=" + position);
        }
        if (insert.isEmpty()) {
            return target;
        }
        if (position == 0) {
            return insert.concat(target);
        } else if (position == targetLen) {
            return target.concat(insert);
        }
        final int insertLen = insert.length();
        final char[] buffer = new char[targetLen + insertLen];
        target.getChars(0, position, buffer, 0);
        insert.getChars(0, insertLen, buffer, position);
        target.getChars(position, targetLen, buffer, position + insertLen);
        return new String(buffer);
    }
    

    【讨论】:

      【解决方案6】:

      对于 Kotlin 帅哥 ;) 来自已接受的答案 (@MikeThomsen's)

      fun String.insert(insertAt: Int, string: String): String {
          return this.substring(0, insertAt) + string + this.substring(insertAt, this.length)
      }
      

      测试✅

      "ThisTest".insert(insertAt = 4, string = "Is").should.equal("ThisIsTest")
      

      【讨论】:

        【解决方案7】:

        你可以使用

        System.out.printf("%4.2f%n", ((float)12345)/100));
        

        根据 cmets,12345/100.0 会更好,使用 double 而不是 float。

        【讨论】:

        • double 可能是更好的选择。 float 只能精确到 6 位。
        • 是的,有人回应的另一个例子是使用 12345/100.0,它更聪明(尽管它最终得到相同的结果。)
        • 吹毛求疵:我认为这不会给出正确的结果,因为 12345/100 = 123 整数,之后只转换为 123.00。 ((float)12345/100) 会起作用。
        • 嘿,好点 - 我没有考虑优先级,主要是因为他第一次运行它会给他截断的结果。将修复帖子(以前说 12345/100,然后投射结果,而不是先扩大值。)
        【解决方案8】:

        String.format("%0d.%02d", d / 100, d % 100);

        【讨论】:

        • 致反对者:重新阅读 OP 详细描述的内容。这为这个问题提供了一个准确的答案:没有浮点数学。将小数点放在正确的位置。也就是说,stackoverflow.com/a/5884413/972128 提供了类似的答案,但使用了浮点数(不需要),目前有 17 个赞成票。
        【解决方案9】:

        如果您使用的系统浮动很昂贵(例如,没有 FPU)或不允许(例如在会计中),您可以使用这样的东西:

            for (int i = 1; i < 100000; i *= 2) {
                String s = "00" + i;
                System.out.println(s.substring(Math.min(2, s.length() - 2), s.length() - 2) + "." + s.substring(s.length() - 2));
            }
        

        否则,DecimalFormat 是更好的解决方案。 (上面的 StringBuilder 变体不适用于小数字 (

        【讨论】:

        • 在会计的情况下,使用 BigDecimal 会更好。
        • @Joseph:你是对的。我不在会计行业,出于性能原因(在嵌入式 Java 中),我主要使用整数作为定点表示,所以 BigDecimal 不是我的选择;-)
        【解决方案10】:

        我认为在某个位置插入字符串的一种更简单、更优雅的解决方案是单行:

        target.replaceAll("^(.{" + position + "})", "$1" + insert);
        

        例如,将缺少的: 插入到时间字符串中:

        "-0300".replaceAll("^(.{3})", "$1:");
        

        它的作用是匹配字符串开头的 position 字符,将其分组,然后用其自身 ($1) 替换该组,然后是 insert 字符串。请注意 replaceAll,即使总是出现一次,因为第一个参数必须是正则表达式。

        当然,它的性能不如 StringBuilder 解决方案,但我相信简洁和优雅作为一种简单易读的单行(与庞大的方法相比)足以使其成为首选解决方案大多数非性能关键用例。

        请注意,出于文档原因,我正在解决标题中的一般问题,当然,如果您正在处理十进制数字,则应该使用已经提出的特定于域的解决方案。

        【讨论】:

          【解决方案11】:
            public static void main(String[] args) {
              char ch='m';
              String str="Hello",k=String.valueOf(ch),b,c;
          
              System.out.println(str);
          
              int index=3;
              b=str.substring(0,index-1 );
              c=str.substring(index-1,str.length());
              str=b+k+c;
          }
          

          【讨论】:

            【解决方案12】:
            // Create given String and make with size 30
            String str = "Hello How Are You";
            
            // Creating StringBuffer Object for right padding
            StringBuffer stringBufferRightPad = new StringBuffer(str);
            while (stringBufferRightPad.length() < 30) {
                stringBufferRightPad.insert(stringBufferRightPad.length(), "*");
            }
            
            System.out.println("after Left padding : " + stringBufferRightPad);
            System.out.println("after Left padding : " + stringBufferRightPad.toString());
            
            // Creating StringBuffer Object for right padding
            StringBuffer stringBufferLeftPad = new StringBuffer(str);
            while (stringBufferLeftPad.length() < 30) {
                stringBufferLeftPad.insert(0, "*");
            }
            System.out.println("after Left padding : " + stringBufferLeftPad);
            System.out.println("after Left padding : " + stringBufferLeftPad.toString());
            

            【讨论】:

            • 欢迎来到 Stack Overflow!一般来说,如果答案包括对代码的用途的解释,以及为什么在不介绍其他人的情况下解决问题的原因,答案会更有帮助。感谢您提高答案的参考价值并使其更易于理解!
            • 请不要使用 StringBuffer,因为它在 2004 年被 StringBuilder 取代。
            【解决方案13】:

            试试这个:

            public String ConvertMessage(String content_sendout){
            
                    //use unicode (004E00650077) need to change to hex (&#x004E&#x;0065&#x;0077;) first ;
                    String resultcontent_sendout = "";
                    int i = 4;
                    int lengthwelcomemsg = content_sendout.length()/i;
                    for(int nadd=0;nadd<lengthwelcomemsg;nadd++){
                        if(nadd == 0){
                            resultcontent_sendout = "&#x"+content_sendout.substring(nadd*i, (nadd*i)+i) + ";&#x";
                        }else if(nadd == lengthwelcomemsg-1){
                            resultcontent_sendout += content_sendout.substring(nadd*i, (nadd*i)+i) + ";";
                        }else{
                            resultcontent_sendout += content_sendout.substring(nadd*i, (nadd*i)+i) + ";&#x";
                        }
                    }
                    return resultcontent_sendout;
                }
            

            【讨论】:

              猜你喜欢
              • 2020-04-22
              • 1970-01-01
              • 1970-01-01
              • 2021-11-11
              • 2011-05-20
              • 2019-07-31
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多