Bagaimana cara memasukkan karakter dalam string pada posisi tertentu?


155

Saya mendapatkan intnilai 6 digit. Saya ingin menampilkannya sebagai Stringdengan titik desimal (.) Pada 2 digit dari akhir int. Saya ingin menggunakan floattetapi disarankan untuk menggunakan Stringuntuk menampilkan tampilan yang lebih baik (bukan 1234.5akan 1234.50). Oleh karena itu, saya memerlukan fungsi yang akan mengambil intparameter sebagai dan mengembalikan yang diformat Stringdengan benar dengan angka desimal 2 digit dari akhir.

Mengatakan:

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

Jawaban:


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

6
String tidak berubah. Meskipun ini berfungsi, menggunakan sesuatu seperti StringBuilder secara moral benar, belum lagi akan membuat kode Anda lebih cepat.
wheresmycookie

7
Lupakan StringBuilder. Dengan pemformatan seperti ini, String.format adalah opsi terbaik yang tersedia.
NobleUplift

33
Tidak ada loop, ini adalah kasus gabungan sederhana dan kompiler harus mengoptimalkannya menggunakan pembangun string, untuk keterbacaan saya lebih suka menggunakan operator +, tidak perlu dalam hal ini untuk menggunakan StringBuilder secara eksplisit. Menggunakan solusi "StringBuilder" karena lebih cepat tidak menghormati aturan optimasi. Kode untuk keterbacaan. Optimalkan setelah pembuatan profil dan hanya jika diperlukan. en.wikipedia.org/wiki/Program_optimization#Quotes
Remi Morin

17
Anda tidak perlu x.length () pada panggilan substring kedua.
crazyGuy

1
Solusi ini akan gagal ketika jumlahnya berbeda jumlah digit. Untuk 12345 akan menghasilkan 1234.5 dan untuk 1234567 akan menjadi 1234.567. Jika Anda selalu ingin 2 digit terakhir menjadi setelah titik desimal, pastikan jumlahnya memiliki setidaknya 3 digit dan kemudian lakukanx = x.substring(0, x.length()-2) + "." + x.substring(x.length()-2);
Teodor Marinescu

210

Seperti disebutkan dalam komentar, StringBuilder mungkin merupakan implementasi yang lebih cepat daripada menggunakan StringBuffer . Seperti yang disebutkan dalam dokumen Java:

Kelas ini menyediakan API yang kompatibel dengan StringBuffer, tetapi tanpa jaminan sinkronisasi. Kelas ini dirancang untuk digunakan sebagai pengganti drop-in untuk StringBuffer di tempat-tempat di mana buffer string sedang digunakan oleh utas tunggal (seperti umumnya casing). Jika memungkinkan, disarankan agar kelas ini digunakan dalam preferensi untuk StringBuffer karena akan lebih cepat di sebagian besar implementasi.

Penggunaan:

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

Atau jika Anda perlu sinkronisasi gunakan StringBuffer dengan penggunaan serupa:

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

1
Solusi ini berfungsi untuk string apa pun> = 4 karakter: string "111" memberi saya ".111", dan apa pun yang kurang dari itu menghasilkan java.lang.StringIndexOutOfBoundsException(mencoba mengakses referensi yang tidak ada).
sotrh

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

Saya akan menyarankan menggunakan java.math.BigDecimalkarena menggunakan doubledapat menyebabkan kesalahan pembulatan . Jika kecepatan lebih berharga daripada presisi doublelebih baik.
sotrh

5

Dalam kebanyakan kasus penggunaan, menggunakan StringBuilder(seperti yang sudah dijawab) adalah cara yang baik untuk melakukan ini. Namun, jika kinerja penting, ini bisa menjadi alternatif yang baik.

/**
 * 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

Menggunakan ApacheCommons3 StringUtils, Anda juga bisa melakukannya

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

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

pada dasarnya meringkas penggabungan tetapi lebih pendek jika Anda tidak keberatan menggunakan perpustakaan, atau sudah bergantung pada StringUtils


2

Anda bisa menggunakannya

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

Sesuai komentar, 12345 / 100.0 akan lebih baik, seperti penggunaan double bukan float.


2
doublemungkin pilihan yang lebih baik. float hanya akurat hingga 6 digit.
Peter Lawrey

1
Ya, contoh lain yang ditanggapi seseorang adalah menggunakan 12345 / 100.0, yang lebih pintar (meskipun berakhir dengan hasil yang sama.)
Joseph Ottinger

Nitpicking: Saya pikir ini tidak akan memberikan hasil yang benar, karena 12345/100 = 123 dalam bilangan bulat dan hanya dilemparkan ke 123,00 sesudahnya. ((float) 12345/100) akan berfungsi.
rurouni

Heh, poin bagus - saya tidak mempertimbangkan, terutama karena pertama kali dia menjalankannya itu akan memberinya hasil yang terpotong. Akan memperbaiki pos (yang biasanya mengatakan 12345/100, lalu memberikan hasilnya, alih-alih melebarkan nilainya terlebih dahulu.)
Joseph Ottinger

0

Jika Anda menggunakan sistem di mana float mahal (misalnya tidak ada FPU) atau tidak diizinkan (misalnya dalam akuntansi) Anda bisa menggunakan sesuatu seperti ini:

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

Kalau tidak, DecimalFormat adalah solusi yang lebih baik. (varian StringBuilder di atas tidak akan berfungsi dengan angka kecil (<100)


2
Dalam hal akuntansi, Anda akan lebih baik dengan BigDecimal.
Joseph Ottinger

@ Joseph: Anda benar. Saya tidak dalam akuntansi dan saya kebanyakan menggunakan ints sebagai representasi fixedpoint untuk alasan kinerja (dalam embedded java), jadi BigDecimal bukan pilihan saya ;-)
rurouni

0

Saya pikir solusi yang lebih sederhana dan lebih elegan untuk menyisipkan sebuah String dalam posisi tertentu adalah one-liner ini:

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

Misalnya, untuk memasukkan yang hilang :ke dalam String waktu:

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

Apa yang dilakukannya adalah, mencocokkan positionkarakter dari awal string, mengelompokkan itu, dan mengganti grup dengan dirinya sendiri ( $1) diikuti oleh insertstring. Pikirkan replall, meskipun selalu ada satu kejadian, karena parameter pertama harus berupa regex.

Tentu saja itu tidak memiliki kinerja yang sama dengan solusi StringBuilder, tapi saya percaya kesederhanaan dan keanggunan sebagai sederhana dan lebih mudah dibaca satu-liner (dibandingkan dengan metode besar) sudah cukup untuk menjadikannya solusi pilihan di sebagian besar non kinerja kasus penggunaan-kritis.

Catatan Saya sedang memecahkan masalah umum dalam judul untuk alasan dokumentasi, tentu saja jika Anda berurusan dengan angka desimal Anda harus menggunakan solusi spesifik domain yang sudah diusulkan.


0

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


Kepada siapa pun yang memilih ini: Baca kembali apa yang OP jelaskan secara terperinci. Ini memberikan jawaban yang tepat untuk masalah: Tidak ada matematika floating point. Letakkan titik desimal di tempat yang tepat. Untuk kecerdasan, stackoverflow.com/a/5884413/972128 memberikan jawaban yang sama tetapi menggunakan floating point (tidak diinginkan), dan memiliki 17 upvotes saat ini.
kkurian

0

Untuk Kotlin dudes;) dari jawaban yang diterima (@ MikeThomsen's)

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

Tes ✅

"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
Selamat Datang di Stack Overflow! Secara umum, jawaban akan jauh lebih membantu jika mereka menyertakan penjelasan tentang apa yang dimaksudkan untuk dilakukan oleh kode, dan mengapa itu memecahkan masalah tanpa memperkenalkan orang lain. Terima kasih telah meningkatkan nilai referensi jawaban dan membuatnya lebih mudah dimengerti!
Tim Diekmann

Tolong jangan gunakan StringBuffer karena digantikan oleh StringBuilder pada 2004.
Peter Lawrey

-2

Coba ini :

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;
    }
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.