Как вставить символ в строку в определенной позиции?


155

Я получаю intс 6-значным значением. Я хочу отобразить его как Stringс десятичной точкой (.) В 2 цифры от конца int. Я хотел использовать, floatно было предложено использовать Stringдля лучшего вывода на дисплей (а 1234.5не будет 1234.50). Поэтому мне нужна функция, которая будет принимать в intкачестве параметра и возвращать правильно отформатированный Stringс десятичной точкой 2 цифры от конца.

Сказать:

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

Ответы:


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

6
Строки неизменны. Хотя это работает, использование чего-то вроде StringBuilder является морально правильным, не говоря уже о том, что ваш код будет работать быстрее.
Wheresmycookie

7
Забудь StringBuilder. С таким форматированием String.format - лучший доступный вариант.
NobleUplift

33
Цикла нет, это простой случай конкатенации, и компилятор должен оптимизировать его, используя построитель строк, для удобства чтения я предпочитаю использовать оператор +, в этом случае нет необходимости явно использовать StringBuilder. Использование решения "StringBuilder", потому что это быстрее, не соблюдайте правила оптимизации. Код для удобочитаемости. Оптимизируйте после профилирования и только там, где это требуется. ru.wikipedia.org/wiki/Program_optimization#Quotes
Реми Морин,

17
Вам не нужен x.length () для второго вызова подстроки.
crazyGuy

1
Это решение не будет выполнено, когда число будет другим числом. Для 12345 он выдаст 1234,5, а для 1234567 будет 1234,567. Если вы хотите всегда последние 2 цифры , чтобы быть после десятичной точки, то убедитесь , что номер имеет по крайней мере 3 цифры , а затем сделатьx = x.substring(0, x.length()-2) + "." + x.substring(x.length()-2);
Теодора Маринеску

210

Как упоминалось в комментариях, StringBuilder , вероятно, является более быстрой реализацией, чем использование StringBuffer . Как упоминалось в документации по Java:

Этот класс предоставляет API-интерфейс, совместимый с StringBuffer, но без гарантии синхронизации. Этот класс предназначен для использования в качестве вставной замены для StringBuffer в местах, где строковый буфер использовался одним потоком (как это обычно бывает). Там, где это возможно, рекомендуется использовать этот класс вместо StringBuffer, так как он будет быстрее в большинстве реализаций.

Использование :

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

Или, если вам нужна синхронизация, используйте StringBuffer с аналогичным использованием:

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

1
Это решение работает для любой строки> = 4 символа: строка «111» дала мне «.111», и все, что меньше этого, приводит к java.lang.StringIndexOutOfBoundsException(попытка получить доступ к ссылке, которая не существует).
Sotrh

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

Я бы предложил использовать java.math.BigDecimalкак использование doubleможет вызвать ошибку округления . Если скорость важнее, чем точность double, тем лучше.
Sotrh

5

В большинстве случаев использование StringBuilder(как уже ответили) является хорошим способом сделать это. Однако, если производительность имеет значение, это может быть хорошей альтернативой.

/**
 * 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, вы также можете сделать

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

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

в основном это конкатенация подстрок, но короче, если вы не возражаете против использования библиотек, или уже в зависимости от StringUtils


2

Вы могли бы использовать

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

Согласно комментариям, 12345 / 100.0 будет лучше, так же как и использование double вместо float.


2
doubleможет быть лучшим выбором. с плавающей точкой с точностью до 6 цифр.
Питер Лори

1
Да, еще один пример, на который кто-то ответил, это использовать 12345 / 100.0, что умнее (хотя в итоге получается тот же результат).
Джозеф Оттингер

Nitpicking: я думаю, что это не даст правильный результат, потому что 12345/100 = 123 в целых числах и будет приведен к 123.00 после этого. ((float) 12345/100) будет работать.
Руруни

Хех, хорошая мысль - я не принимал во внимание приоритет, в основном потому, что в первый раз, когда он запускал его, это давало ему усеченный результат. Исправит пост (который раньше говорил 12345/100, затем приводил результат, вместо того, чтобы сначала расширять значение.)
Джозеф Оттингер

0

Если вы используете систему, в которой float стоит дорого (например, без FPU) или не разрешен (например, в бухгалтерском учете), вы можете использовать что-то вроде этого:

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

В противном случае DecimalFormat является лучшим решением. (приведенный выше вариант StringBuilder не будет работать с небольшими числами (<100)


2
В случае бухгалтерского учета вам будет лучше с BigDecimal.
Джозеф Оттингер

@ Джозеф: Вы правы. Я не в бухгалтерии, и я в основном использую int как представление с фиксированной точкой по соображениям производительности (во встроенном java), поэтому BigDecimal не мой выбор ;-)
rurouni

0

Я думаю, что более простое и элегантное решение для вставки строки в определенную позицию - это одна строка:

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

Например, чтобы вставить отсутствующую :строку времени:

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

Что он делает, сопоставляет positionсимволы в начале строки, группирует их и заменяет группу на себя ( $1), за которой следуетinsert строка. Обратите внимание на replaceAll, хотя всегда есть одно вхождение, потому что первый параметр должен быть регулярным выражением.

Конечно, он не обладает той же производительностью, что и решение StringBuilder, но я считаю, что краткость и элегантность в виде простого и удобного для чтения однострочного текста (по сравнению с огромным методом) достаточны для того, чтобы сделать его предпочтительным решением в большинстве не производительных систем. -критические сценарии использования.

Примечание. Я решаю общую проблему в заголовке по причинам, связанным с документацией. Конечно, если вы имеете дело с десятичными числами, вам следует использовать уже предложенные решения для конкретных областей.


0

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


Для тех, кто отрицал это: перечитайте то, что ОП подробно описало. Это дает точный ответ на проблему: нет математики с плавающей запятой. Ставит десятичную точку в нужном месте. Иными словами , stackoverflow.com/a/5884413/972128 дает аналогичный ответ, но использует с плавающей запятой (не желательно) и имеет в настоящее время 17 голосов.
Ккурян

0

Для котлинских парней;) из принятого ответа (@ MikeThomsen's)

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

Тест ✅

"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
Добро пожаловать в стек переполнения! Как правило, ответы гораздо полезнее, если они включают в себя объяснение того, для чего предназначен код, и почему это решает проблему, не представляя других. Спасибо за то, что улучшили ссылочную ценность ответа и сделали его более понятным!
Тим Дикманн

Пожалуйста, не используйте StringBuffer, так как он был заменен StringBuilder в 2004 году.
Питер Лори

-2

Попробуй это :

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;
    }
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.