Come inserire un carattere in una stringa in una determinata posizione?


155

Sto entrando in un intvalore di 6 cifre. Voglio visualizzarlo come a Stringcon un punto decimale (.) A 2 cifre dalla fine di int. Volevo usare un floatma mi è stato suggerito di usarlo Stringper un migliore output di visualizzazione (invece che 1234.5lo sarà 1234.50). Pertanto, ho bisogno di una funzione che prenda un intparametro come e restituisca il valore correttamente formattato Stringcon un punto decimale 2 cifre dalla fine.

Dire:

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,

Risposte:


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

6
Le stringhe sono immutabili. Mentre funziona, usare qualcosa come StringBuilder è moralmente corretto, per non parlare renderà il tuo codice più veloce.
wheresmycookie il

7
Dimentica StringBuilder. Con una formattazione come questa, String.format è la migliore opzione disponibile.
NobleUplift,

33
Non esiste un ciclo, è un semplice caso di concatenazione e il compilatore dovrebbe ottimizzarlo utilizzando un generatore di stringhe, per la leggibilità preferisco usare l'operatore +, in questo caso non è necessario utilizzare StringBuilder in modo esplicito. Utilizzando la soluzione "StringBuilder" perché è più veloce non rispettare le regole di ottimizzazione. Codice per leggibilità. Ottimizza dopo la profilazione e solo dove è richiesto. en.wikipedia.org/wiki/Program_optimization#Quotes
Remi Morin

17
Non è necessario x.length () sulla seconda chiamata di sottostringa.
crazyGuy

1
Questa soluzione fallirà quando il numero è un numero diverso di cifre. Per 12345 produrrà 1234.5 e per 1234567 sarà 1234.567. Se vuoi sempre che le ultime 2 cifre siano dopo il punto decimale, assicurati che il numero contenga almeno 3 cifre e poi fallox = x.substring(0, x.length()-2) + "." + x.substring(x.length()-2);
Teodor Marinescu

210

Come menzionato nei commenti, uno StringBuilder è probabilmente un'implementazione più rapida rispetto all'utilizzo di uno StringBuffer . Come menzionato nei documenti Java:

Questa classe fornisce un'API compatibile con StringBuffer, ma senza alcuna garanzia di sincronizzazione. Questa classe è progettata per essere utilizzata come sostituto drop-in per StringBuffer in luoghi in cui il buffer di stringa veniva utilizzato da un singolo thread (come generalmente accade). Laddove possibile, si consiglia di utilizzare questa classe preferibilmente a StringBuffer poiché sarà più veloce nella maggior parte delle implementazioni.

Utilizzo:

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

O se hai bisogno di sincronizzazione usa StringBuffer con un utilizzo simile:

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

1
Questa soluzione funziona per qualsiasi stringa> = 4 caratteri: la stringa "111" mi ha dato ".111" e qualsiasi cosa inferiore a quella risulta in un java.lang.StringIndexOutOfBoundsException(tentativo di accedere a un riferimento che non esiste).
sotrh,

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

Suggerirei di usare java.math.BigDecimalcome usare doublepuò causare errori di arrotondamento . Se la velocità è più preziosa della precisione doubleè meglio.
sotrh,

5

Nella maggior parte dei casi d'uso, utilizzare un StringBuilder(come già risposto) è un buon modo per farlo. Tuttavia, se le prestazioni sono importanti, questa potrebbe essere una buona 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, potresti anche farlo

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

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

è fondamentalmente concatenazione di sottostringhe ma più breve se non ti dispiace usare le librerie o già a seconda di StringUtils


2

Puoi usare

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

Secondo i commenti, 12345 / 100.0 sarebbe meglio, così come l'uso del doppio invece del float.


2
doublepotrebbe essere una scelta migliore. float ha una precisione di soli 6 cifre.
Peter Lawrey,

1
Sì, un altro esempio con cui qualcuno ha risposto è stato l'uso di 12345 / 100.0, che è più intelligente (anche se finisce con lo stesso risultato.)
Joseph Ottinger

Nitpicking: penso che questo non darà il risultato giusto, perché 12345/100 = 123 in numero intero e viene lanciato solo a 123,00 in seguito. ((float) 12345/100) avrebbe funzionato.
rurouni,

Heh, buon punto - Non stavo prendendo in considerazione la precedenza, soprattutto perché la prima volta che lo ha eseguito gli avrebbe dato il risultato troncato. Risolverà il post (che in precedenza diceva 12345/100, quindi lanciava il risultato, invece di allargare prima il valore.)
Joseph Ottinger,

0

Se si utilizza un sistema in cui float è costoso (ad es. Nessuna FPU) o non consentito (ad es. In contabilità) è possibile utilizzare qualcosa del genere:

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

Altrimenti DecimalFormat è la soluzione migliore. (la variante di StringBuilder sopra non funziona con numeri piccoli (<100)


2
Nel caso della contabilità, staresti meglio con BigDecimal.
Joseph Ottinger,

@Joseph: hai ragione. Non sono in contabilità e uso principalmente ints come rappresentazione a virgola fissa per motivi di prestazioni (in Java incorporato), quindi BigDecimal non è la mia scelta ;-)
rurouni

0

Penso che una soluzione più semplice ed elegante per inserire una stringa in una certa posizione sarebbe questa linea singola:

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

Ad esempio, per inserire un elemento mancante :in una stringa temporale:

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

Quello che fa è, trova i positioncaratteri dall'inizio della stringa, li raggruppa e sostituisce il gruppo con se stesso ( $1) seguito dalinsert stringa. Badate a ReplaceAll, anche se c'è sempre un'occorrenza, perché il primo parametro deve essere una regex.

Ovviamente non ha le stesse prestazioni della soluzione StringBuilder, ma credo che la succinta e l'eleganza di un one-liner semplice e più facile da leggere (rispetto a un metodo enorme) sia sufficiente per renderlo la soluzione preferita nella maggior parte delle non prestazioni - casi d'uso critici.

Nota Sto risolvendo il problema generico nel titolo per motivi di documentazione, ovviamente se hai a che fare con numeri decimali dovresti usare le soluzioni specifiche del dominio già proposte.


0

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


A chiunque abbia annullato il voto: rileggere ciò che l'OP ha descritto in dettaglio. Ciò fornisce una risposta esatta al problema: nessuna matematica in virgola mobile. Mette il punto decimale nel posto giusto. In altre parole, stackoverflow.com/a/5884413/972128 fornisce una risposta simile ma utilizza il virgola mobile (non desiderato) e al momento ha 17 voti positivi.
kkurian

0

Per i ragazzi di Kotlin;) dalla risposta accettata (@ MikeThomsen)

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

Test ✅

"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
Benvenuto in Stack Overflow! In generale, le risposte sono molto più utili se includono una spiegazione di ciò che il codice è destinato a fare e perché risolve il problema senza introdurre altri. Grazie per migliorare il valore di riferimento della risposta e renderlo più comprensibile!
Tim Diekmann,

Si prega di non utilizzare StringBuffer poiché è stato sostituito da StringBuilder nel 2004.
Peter Lawrey,

-2

Prova questo :

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;
    }
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.