¿Cómo insertar un carácter en una cadena en una posición determinada?


155

Me estoy metiendo en un intcon un valor de 6 dígitos. Quiero mostrarlo como a Stringcon un punto decimal (.) A 2 dígitos desde el final de int. Quería usar un floatpero se me sugirió usar Stringpara una mejor salida de pantalla (en lugar de 1234.5lo será 1234.50). Por lo tanto, necesito una función que tome un intparámetro como y devuelva el formato correcto Stringcon un punto decimal a 2 dígitos del final.

Decir:

int j= 123456 
Integer.toString(j); 

//processing...

//output : 1234.56

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

Respuestas:


195
int j = 123456;
String x = Integer.toString(j);
x = x.substring(0, 4) + "." + x.substring(4, x.length());

66
Las cuerdas son inmutables. Si bien esto funciona, usar algo como StringBuilder es moralmente correcto, sin mencionar que hará que su código sea más rápido.
wheresmycookie

77
Olvídate de StringBuilder. Con un formato como este, String.format es la mejor opción disponible.
NobleUplift

33
No hay bucle, es un caso de concatenación simple y el compilador debe optimizarlo usando un generador de cadenas, para facilitar la lectura, prefiero usar el operador +, en este caso no hay necesidad de usar StringBuilder explícitamente. Usando la solución "StringBuilder" porque es más rápido, no respete las reglas de optimización. Código de legibilidad. Optimice después de perfilar y solo donde se requiera. en.wikipedia.org/wiki/Program_optimization#Quotes
Remi Morin

17
No necesita x.length () en la segunda llamada de subcadena.
crazyGuy

1
Esta solución fallará cuando el número sea un número diferente de dígitos. Para 12345 generará 1234.5 y para 1234567 será 1234.567. Si siempre quieres que los últimos 2 dígitos estén después del punto decimal, asegúrate de que el número tenga al menos 3 dígitos y luego hazlox = x.substring(0, x.length()-2) + "." + x.substring(x.length()-2);
Teodor Marinescu

210

Como se mencionó en los comentarios, un StringBuilder es probablemente una implementación más rápida que usar un StringBuffer . Como se menciona en los documentos de Java:

Esta clase proporciona una API compatible con StringBuffer, pero sin garantía de sincronización. Esta clase está diseñada para usarse como un reemplazo directo para StringBuffer en lugares donde un único subproceso estaba utilizando el búfer de cadena (como suele ser el caso). Siempre que sea posible, se recomienda que esta clase se use con preferencia a StringBuffer, ya que será más rápida en la mayoría de las implementaciones.

Uso:

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

O si necesita sincronización, use StringBuffer con un uso similar:

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

1
Esta solución funciona para cualquier cadena> = 4 caracteres: la cadena "111" me dio ".111", y cualquier cosa menor que eso da como resultado un java.lang.StringIndexOutOfBoundsException(intentando acceder a una referencia que no existe).
sotrh

17
int yourInteger = 123450;
String s = String.format("%6.2f", yourInteger / 100.0);
System.out.println(s);

Sugeriría usar java.math.BigDecimalcomo usar doublepuede causar un error de redondeo . Si la velocidad es más valiosa que la precisión, doublees mejor.
sotrh

5

En la mayoría de los casos de uso, usar un StringBuilder(como ya se respondió) es una buena manera de hacerlo. Sin embargo, si el rendimiento es importante, esta puede ser una buena alternativa.

/**
 * 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);
}

4

Usando ApacheCommons3 StringUtils, también podrías hacer

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

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

Básicamente es una concatenación de subcadenas, pero más corta si no te importa usar bibliotecas, o ya depende de StringUtils


2

Podrías usar

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

Según los comentarios, 12345 / 100.0 sería mejor, al igual que el uso de doble en lugar de flotante.


2
doublePodría ser una mejor opción. El flotador solo tiene una precisión de 6 dígitos.
Peter Lawrey

1
Sí, otro ejemplo con el que alguien respondió fue usar 12345 / 100.0, que es más inteligente (aunque termina con el mismo resultado)
Joseph Ottinger

Nitpicking: Creo que esto no dará el resultado correcto, porque 12345/100 = 123 en entero y solo se lanza a 123.00 después. ((flotante) 12345/100) funcionaría.
Rurouni 05 de

Je, buen punto: no estaba teniendo en cuenta la prioridad, principalmente porque la primera vez que lo ejecutó le daría el resultado truncado. Arreglará la publicación (que solía decir 12345/100, luego emitió el resultado, en lugar de ampliar el valor primero)
Joseph Ottinger

0

Si está utilizando un sistema donde el flotador es costoso (por ejemplo, sin FPU) o no está permitido (por ejemplo, en contabilidad), podría usar algo como esto:

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

De lo contrario, DecimalFormat es la mejor solución. (La variante StringBuilder anterior no funcionará con números pequeños (<100)


2
En el caso de la contabilidad, sería mejor con BigDecimal.
Joseph Ottinger

@ Joseph: Tienes razón. No estoy en contabilidad y uso principalmente ints como una representación de punto fijo por razones de rendimiento (en Java incrustado), por lo que BigDecimal no es mi elección ;-)
rurouni

0

Creo que una solución más simple y elegante para insertar una cadena en una determinada posición sería esta frase:

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

Por ejemplo, para insertar una falta :en una cadena de tiempo:

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

Lo que hace es, coincide con los positioncaracteres desde el principio de la cadena, agrupa eso y reemplaza el grupo con sí mismo ( $1) seguido por elinsert cadena. Tenga en cuenta el replaceAll, aunque siempre haya una ocurrencia, porque el primer parámetro debe ser una expresión regular.

Por supuesto, no tiene el mismo rendimiento que la solución StringBuilder, pero creo que la concisión y la elegancia como una sola línea simple y más fácil de leer (en comparación con un método enorme) es suficiente para convertirla en la solución preferida en la mayoría de los casos sin rendimiento -críticos casos de uso.

Tenga en cuenta que estoy resolviendo el problema genérico en el título por razones de documentación, por supuesto, si se trata de números decimales, debe usar las soluciones específicas de dominio ya propuestas.


0

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


A quien haya votado en contra de esto: vuelva a leer lo que el OP describió en detalle. Esto proporciona una respuesta exacta al problema: no hay matemática de punto flotante. Pone el punto decimal en el lugar correcto. A saber, stackoverflow.com/a/5884413/972128 proporciona una respuesta similar pero usa coma flotante (no deseado), y tiene 17 votos a favor en este momento.
kkurian

0

Para los tipos de Kotlin;) de la respuesta aceptada (@ MikeThomsen's)

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

Prueba ✅

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

-2
  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;
}

-2
// 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());

2
¡Bienvenido a Stack Overflow! En general, las respuestas son mucho más útiles si incluyen una explicación de lo que el código pretende hacer y por qué eso resuelve el problema sin introducir otros. ¡Gracias por mejorar el valor de referencia de la respuesta y hacerla más comprensible!
Tim Diekmann

No use StringBuffer, ya que fue reemplazado por StringBuilder en 2004.
Peter Lawrey

-2

Prueba esto :

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;
    }
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.