Bir karakter dizeye belirli bir konumda nasıl eklenir?


155

int6 basamaklı bir değeri alıyorum . StringSonundan 2 basamaklı bir ondalık basamak (.) İle görüntülemek istiyorum int. Ben kullanmak istedim floatama String(yerine 1234.5olacak 1234.50) daha iyi bir ekran çıkışı için kullanılması önerildi . Bu nedenle, bir intas parametresini alıp düzgün biçimlendirilmiş döndürecek bir işleve ihtiyacım varString bir şekilde ondalık nokta 2 basamak ile .

Söyle:

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

Yanıtlar:


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

6
Teller değişmez. Bu çalışırken, StringBuilder gibi bir şey kullanmak ahlaki olarak doğrudur, bahsetmemek kodunuzu daha hızlı hale getirecektir.
wheresmycookie

7
StringBuilder'i unutun. Böyle bir biçimlendirme ile, String.format mevcut en iyi seçenektir.
NobleUplift

33
Hiçbir döngü yoktur, basit bir birleştirme durumu ve derleyici bir dize oluşturucu kullanarak optimize etmelisiniz, okunabilirlik için + operatörünü kullanmayı tercih ederim, bu durumda StringBuilder'ı açıkça kullanmaya gerek yoktur. Daha hızlı olduğu için "StringBuilder" çözümünü kullanmak, optimizasyon kurallarına uymaz. Okunabilirlik kodu. Profil oluşturduktan sonra ve yalnızca gerektiği yerde optimize edin. en.wikipedia.org/wiki/Program_optimization#Quotes
Remi Morin

17
İkinci alt dize çağrısında x.length () gerekmez.
CrazyGuy

1
Sayı farklı sayıda basamak olduğunda bu çözüm başarısız olur. 12345 için 1234.5 çıktı ve 1234567 için 1234.567 olacaktır. Her zaman son 2 basamağın ondalık basamaktan sonra olmasını istiyorsanız, sayının en az 3 basamak olduğundan emin olun ve sonra yapınx = x.substring(0, x.length()-2) + "." + x.substring(x.length()-2);
Teodor Marinescu

210

Yorumlarda belirtildiği gibi, bir StringBuilder muhtemelen bir StringBuffer kullanmaktan daha hızlı bir uygulamadır . Java belgelerinde belirtildiği gibi:

Bu sınıf, StringBuffer ile uyumlu ancak senkronizasyon garantisi bulunmayan bir API sağlar. Bu sınıf, dize arabelleğinin tek bir iş parçacığı tarafından kullanıldığı yerlerde (genellikle olduğu gibi) StringBuffer için bir yedek değiştirme olarak kullanılmak üzere tasarlanmıştır. Mümkün olduğunda, bu uygulamanın çoğu uygulamada daha hızlı olacağı için StringBuffer'a tercih edilmesi önerilir.

Kullanımı:

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

Veya senkronizasyona ihtiyacınız varsa StringBuffer'ı benzer kullanımla kullanın:

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

1
Bu çözüm, herhangi bir dize> = 4 karakter için çalışır: "111" dizesi bana ".111" verdi ve bundan daha küçük bir şey java.lang.StringIndexOutOfBoundsException(var olmayan bir referansa erişmeye çalışarak) ile sonuçlanır .
sotrh

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

Kullanarak java.math.BigDecimalkullanarak yuvarlama hatasınadouble neden olabilir öneririz . Hız hassasiyetten daha değerliyse daha iyidir. double
sotrh

5

Çoğu kullanım durumunda, StringBuilder(daha önce yanıtlandığı gibi) kullanmak bunu yapmanın iyi bir yoludur. Ancak, performans önemliyse, bu iyi bir alternatif olabilir.

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

ApacheCommons3 StringUtils kullanarak şunları da yapabilirsiniz:

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

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

temelde alt dize birleşimidir, ancak kitaplıkları kullanmayı düşünmüyorsanız veya zaten StringUtils'e bağlıysanız daha kısadır


2

Kullanabilirsin

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

Yorumlara göre, 12345 / 100.0, float yerine double kullanımı daha iyi olurdu.


2
doubledaha iyi bir seçim olabilir. şamandıra sadece 6 basamağa kadar doğrudur.
Peter Lawrey

1
Evet, birisinin yanıt verdiği başka bir örnek, daha akıllı olan 12345 / 100.0 kullanmaktı (aynı sonuçla sonuçlansa da)
Joseph Ottinger

Nitpicking: Bunun doğru sonucu vermeyeceğini düşünüyorum, çünkü 12345/100 = 123 tamsayıda ve sadece 123.00'a atıldı. ((şamandıra) 12345/100) işe yarayacaktır.
rurouni

Heh, iyi bir nokta - Önceliği dikkate almıyordum, çoğunlukla ilk kez çalıştırdığı için ona kesilmiş sonucu verecekti. Direği düzeltir (ilk önce değeri genişletmek yerine 12345/100 diyelim, ardından sonucu yayınlar.)
Joseph Ottinger

0

Şamandıranın pahalı olduğu (örn. FPU'suz) veya izin verilmeyen (örneğin muhasebede) bir sistem kullanıyorsanız, aşağıdaki gibi bir şey kullanabilirsiniz:

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

Aksi takdirde DecimalFormat daha iyi bir çözümdür. (yukarıdaki StringBuilder varyantı küçük sayılarla çalışmaz (<100)


2
Muhasebe söz konusu olduğunda, BigDecimal ile daha iyi durumda olursunuz.
Joseph Ottinger

@Joseph: Haklısın. Muhasebede değilim ve çoğunlukla performans nedenleriyle (gömülü java'da) sabit nokta temsili olarak ints kullanıyorum, bu yüzden BigDecimal benim seçimim değil ;-)
rurouni

0

Belirli bir pozisyonda bir String eklemek için daha basit ve daha zarif bir çözümün bu tek astar olacağını düşünüyorum:

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

Örneğin, :bir zaman dizesine eksik eklemek için :

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

Yaptığı şey, positiondizenin başındaki karakterlerle, gruplarla eşleşen ve grubu kendisiyle ( $1) ve ardından geleninsert dizeyle değiştirir. Her zaman tek bir olay olmasına rağmen, tüm parametreye dikkat edin, çünkü ilk parametre bir normal ifade olmalıdır.

Tabii ki StringBuilder çözümü ile aynı performansa sahip değil, ama basit ve okunması kolay bir tek satırlık (büyük bir yönteme kıyasla) özlü ve zarafetin çoğu performansta olmayanlarda tercih edilen çözüm yapmak için yeterli olduğuna inanıyorum -kritik kullanım durumları.

Not Başlıktaki genel sorunu dokümantasyon nedenleriyle çözüyorum, elbette ondalık sayılarla uğraşıyorsanız, daha önce önerilen alana özel çözümleri kullanmalısınız.


0

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


Bunu kim düşürdüyse: OP'nin detaylı olarak açıkladığı şeyi tekrar okuyun. Bu soruna kesin bir cevap verir: Kayan nokta matematiği yok. Ondalık noktasını doğru yere koyar. Zekâ için, stackoverflow.com/a/5884413/972128 benzer bir cevap sağlar, ancak kayan nokta kullanır (istenmez) ve şu anda 17 yukarı oyu vardır.
kkurian

0

Kotlin dudes için;) kabul edilen cevaptan (@ 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")

-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
Stack Overflow'a hoş geldiniz! Genellikle, kodun ne yapmak istediği ve başkalarını tanıtmadan sorunu neden çözdüğüne dair bir açıklama içeriyorsa, cevaplar çok daha yararlıdır. Yanıtlayıcının referans değerini iyileştirdiğiniz ve daha anlaşılır hale getirdiğiniz için teşekkür ederiz!
Tim Diekmann

Lütfen StringBuffer'ı 2004 yılında StringBuilder ile değiştirildiği için kullanmayın.
Peter Lawrey

-2

Bunu dene :

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;
    }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.