Wie füge ich ein Zeichen an einer bestimmten Position in eine Zeichenfolge ein?

155

Ich steige intmit einem 6-stelligen Wert ein. Ich möchte es als Stringmit einem Dezimalpunkt (.) Bei 2 Stellen ab dem Ende von anzeigen int. Ich wollte ein verwenden float, wurde aber vorgeschlagen, es Stringfür eine bessere Anzeigeausgabe zu verwenden (anstatt 1234.5es zu sein 1234.50). Daher benötige ich eine Funktion, die einen intas-Parameter verwendet und den ordnungsgemäß formatierten zurückgibtString 2-fache Dezimalstelle vom Ende zurückgibt.

Sagen:

int j= 123456 
Integer.toString(j); 

//processing...

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

Antworten:

195
int j = 123456;
String x = Integer.toString(j);
x = x.substring(0, 4) + "." + x.substring(4, x.length());
Mike Thomsen
quelle
6
Saiten sind unveränderlich. Während dies funktioniert, ist die Verwendung von StringBuilder moralisch korrekt, ganz zu schweigen davon, dass Ihr Code schneller wird.
Wheresmycookie
7
Vergiss StringBuilder. Bei einer solchen Formatierung ist String.format die beste verfügbare Option.
NobleUplift
33
Es gibt keine Schleife, es ist ein einfacher Verkettungsfall, und der Compiler sollte ihn mithilfe eines String-Builders optimieren. Aus Gründen der Lesbarkeit bevorzuge ich den Operator +. In diesem Fall muss StringBuilder nicht explizit verwendet werden. Verwenden Sie die "StringBuilder" -Lösung, weil sie schneller ist. Beachten Sie die Optimierungsregeln nicht. Code für die Lesbarkeit. Optimieren Sie nach der Profilerstellung und nur dort, wo es erforderlich ist. en.wikipedia.org/wiki/Program_optimization#Quotes
Remi Morin
17
Sie benötigen x.length () beim zweiten Teilstring-Aufruf nicht.
crazyGuy
1
Diese Lösung schlägt fehl, wenn die Anzahl eine andere Anzahl von Ziffern ist. Für 12345 wird 1234.5 ausgegeben und für 1234567 wird 1234.567 ausgegeben. Wenn Sie immer möchten, dass die letzten 2 Ziffern nach dem Dezimalpunkt liegen, stellen Sie sicher, dass die Zahl mindestens 3 Ziffern hat, und tun Sie dies dannx = x.substring(0, x.length()-2) + "." + x.substring(x.length()-2);
Teodor Marinescu
210

Wie in den Kommentaren erwähnt, ist ein StringBuilder wahrscheinlich eine schnellere Implementierung als die Verwendung eines StringBuffers . Wie in den Java-Dokumenten erwähnt:

Diese Klasse bietet eine API, die mit StringBuffer kompatibel ist, jedoch keine Garantie für die Synchronisierung bietet. Diese Klasse ist als Drop-In-Ersatz für StringBuffer an Stellen vorgesehen, an denen der String-Puffer von einem einzelnen Thread verwendet wurde (wie dies im Allgemeinen der Fall ist). Nach Möglichkeit wird empfohlen, diese Klasse gegenüber StringBuffer zu verwenden, da sie bei den meisten Implementierungen schneller ist.

Verwendung :

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

Oder wenn Sie eine Synchronisation benötigen, verwenden Sie die StringBuffer mit ähnlicher Verwendung:

String str = Integer.toString(j);
str = new StringBuffer(str).insert(str.length()-2, ".").toString();
blo0p3r
quelle
1
Diese Lösung funktioniert für jede Zeichenfolge> = 4 Zeichen: Die Zeichenfolge "111" gab mir ".111", und alles andere führt zu einem java.lang.StringIndexOutOfBoundsException(Versuch, auf eine nicht vorhandene Referenz zuzugreifen).
17.
17
int yourInteger = 123450;
String s = String.format("%6.2f", yourInteger / 100.0);
System.out.println(s);
Itay Maman
quelle
Ich würde vorschlagen , mit java.math.BigDecimalwie die Verwendung doubleverursachen können Rundungsfehler . Wenn Geschwindigkeit mehr wert ist als Präzision, doubleist sie besser.
17.
5

In den meisten Anwendungsfällen ist die Verwendung von a StringBuilder(wie bereits beantwortet) ein guter Weg, dies zu tun. Wenn es jedoch auf die Leistung ankommt, kann dies eine gute Alternative sein.

/**
 * 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);
}
Müller
quelle
4

Mit ApacheCommons3 StringUtils können Sie dies auch tun

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

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

Es ist im Grunde eine Verkettung von Teilzeichenfolgen, aber kürzer, wenn Sie nichts dagegen haben, Bibliotheken zu verwenden, oder bereits abhängig von StringUtils

Gurke
quelle
2

Du könntest benutzen

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

Gemäß den Kommentaren wäre 12345 / 100.0 besser, ebenso wie die Verwendung von double anstelle von float.

Joseph Ottinger
quelle
2
doublekönnte eine bessere Wahl sein. float ist nur auf 6 Stellen genau.
Peter Lawrey
1
Ja, ein anderes Beispiel, mit dem jemand geantwortet hat, war die Verwendung von 12345 / 100.0, was klüger ist (obwohl es das gleiche Ergebnis
liefert
Nitpicking: Ich denke, dies wird nicht das richtige Ergebnis liefern, da 12345/100 = 123 in Integer ist und erst danach auf 123.00 umgewandelt wird. ((float) 12345/100) würde funktionieren.
Rurouni
Heh, guter Punkt - ich habe den Vorrang nicht berücksichtigt, hauptsächlich, weil er beim ersten Mal das verkürzte Ergebnis erhalten würde. Wird den Beitrag reparieren (der früher 12345/100 sagte, dann das Ergebnis umsetzen, anstatt zuerst den Wert zu erweitern)
Joseph Ottinger
0

Wenn Sie ein System verwenden, bei dem Float teuer (z. B. keine FPU) oder nicht zulässig (z. B. in der Buchhaltung) ist, können Sie Folgendes verwenden:

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

Ansonsten ist das DecimalFormat die bessere Lösung. (Die obige StringBuilder-Variante funktioniert nicht mit kleinen Zahlen (<100).

rurouni
quelle
2
Im Falle der Buchhaltung sind Sie mit BigDecimal besser dran.
Joseph Ottinger
@ Joseph: Du hast recht. Ich bin nicht in der Buchhaltung und ich benutze Ints meistens als Fixpunktdarstellung aus Leistungsgründen (in Embedded Java), also ist BigDecimal nicht meine Wahl ;-)
rurouni
0

Ich denke, eine einfachere und elegantere Lösung zum Einfügen eines Strings an einer bestimmten Position wäre dieser Einzeiler:

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

So fügen Sie beispielsweise eine fehlende Zeichenfolge :in eine Zeitzeichenfolge ein:

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

Was es tut, ist, positionZeichen vom Anfang der Zeichenfolge abzugleichen, diese zu gruppieren und die Gruppe durch sich selbst ( $1) zu ersetzen, gefolgt voninsert Zeichenfolge ersetzt. Beachten Sie das replaceAll, auch wenn es immer ein Vorkommen gibt, da der erste Parameter ein regulärer Ausdruck sein muss.

Natürlich hat es nicht die gleiche Leistung wie die StringBuilder-Lösung, aber ich glaube, dass die Prägnanz und Eleganz eines einfachen und leichter lesbaren Einzeilers (im Vergleich zu einer großen Methode) ausreicht, um es zur bevorzugten Lösung für die meisten Nicht-Leistung zu machen -kritische Anwendungsfälle.

Hinweis: Ich löse das generische Problem im Titel aus Dokumentationsgründen. Wenn Sie mit Dezimalzahlen arbeiten, sollten Sie natürlich die bereits vorgeschlagenen domänenspezifischen Lösungen verwenden.

Luan Nico
quelle
0

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

kkurian
quelle
An alle, die dies abgelehnt haben: Lesen Sie noch einmal, was das OP ausführlich beschrieben hat. Dies liefert eine genaue Antwort auf das Problem: Keine Gleitkomma-Mathematik. Setzt den Dezimalpunkt an die richtige Stelle. Nämlich, stackoverflow.com/a/5884413/972128 stellt eine ähnliche Antwort verwendet aber Gleitkomma- (nicht erwünscht), und hat 17 upvotes zu diesem Zeitpunkt.
kkurian
0

Für Kotlin Jungs;) aus der akzeptierten Antwort (@ MikeThomsen's)

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")
theapache64
quelle
-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;
}
Miya
quelle
-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());
Nagendra Mishra
quelle
2
Willkommen bei Stack Overflow! Im Allgemeinen sind Antworten viel hilfreicher, wenn sie eine Erklärung enthalten, was der Code tun soll und warum dies das Problem löst, ohne andere einzuführen. Vielen Dank, dass Sie den Referenzwert der Antwort verbessert und verständlicher gemacht haben!
Tim Diekmann
Bitte verwenden Sie StringBuffer nicht, da er 2004 durch StringBuilder ersetzt wurde.
Peter Lawrey
-2

Versuche dies :

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;
    }
Pattanai Pornpibul
quelle