Парсинг чисел с запятой в Java: альтернативы Double.valueOf()

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Для преобразования строки с числом, где запятая выполняет функцию десятичного разделителя, в double, используйте DecimalFormat с DecimalFormatSymbols, основываясь на локальном стандарте:

Java
Скопировать код
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.Locale;

public class ParseDoubleWithComma {
    public static void main(String[] args) {
        String numberStr = "123,456"; // Представим, что это Франция!
        DecimalFormatSymbols symbols = new DecimalFormatSymbols(Locale.FRANCE);
        DecimalFormat format = new DecimalFormat("###,##0.00", symbols);
        try {
            double number = format.parse(numberStr).doubleValue(); // Преобразование выполнено!
            System.out.println(number); // Вывод: 123.456 – вот так-то!
        } catch (Exception e) {
            e.printStackTrace(); // Ой, ошибка!
        }
    }
}

Выражение DecimalFormat плюс символы локали позволит управлять ситуацией с запятой.

Кинга Идем в IT: пошаговый план для смены профессии

Непосредственное использование NumberFormat

Если требуется скорее обработать число, пробуйте NumberFormat. Вот пример использования:

Java
Скопировать код
String numberStr = "123,456";
NumberFormat nf = NumberFormat.getInstance(Locale.FRANCE);
double number = nf.parse(numberStr).doubleValue();  // Итак, number равен 123.456 – вот так!

С использованием NumberFormat, разбор проходит без проблем!

Быстрый и не изысканный способ

Если вам срочно требуется преобразовать строку в Double, вы можете воспользоваться простой заменой:

Java
Скопировать код
String numberStr = "123,456";
double number = Double.parseDouble(numberStr.replace(',', '.')); // Производим замену запятой на точку!

Данный подход удобен и работает достаточно хорошо, однако, он не учитывает локаль, что может привести к проблемам!

При необходимости большей гибкости применяйте регулярные выражения

Регулярные выражения не всегда оптимальны, но они помогают, когда формат числа далек от стандарта:

Java
Скопировать код
String numberStr = "123,456";
numberStr = numberStr.replaceAll("([^\\d,]|(?<=\\d),(?=\\d{3}))+", "").replace(',', '.');
double number = Double.parseDouble(numberStr); // С регулярными выражениями всё под контролем!

Такой подход медленнее, чем String.replace(), но необходим, когда локаль не указана.

Балансировка между различными локалями

Если ваш код должен грамотно работать с разнообразными локалями, NumberFormat станет вашим спасением:

Java
Скопировать код
Locale userLocale = Locale.getDefault(); // Получаем локаль пользователя
DecimalFormatSymbols symbols = new DecimalFormatSymbols(userLocale); // Настраиваем символы под локаль
DecimalFormat format = new DecimalFormat("###,##0.00", symbols); // Формат теперь подстроен под локаль!

Визуализация

Процесс разбора числа с запятой можно вообразить как обратный отсчёт:

Markdown
Скопировать код
Обратный отсчёт с точкой: | 10.9.8.7.6.5.4.3.2.1 |

Теперь заменим точки на запятые:

Markdown
Скопировать код
Обратный отсчёт с запятой: | 10,9,8,7,6,5,4,3,2,1 |

Для успешного "запуска" (преобразования числа) необходимо преобразовать каждую запятую (,) в точку (.) :

Markdown
Скопировать код
🚀 --(Разбор)--> | 10.9.8.7.6.5.4.3.2.1 | --(Старт!)--> 🌙

Чтобы избежать ошибок при "запуске", используйте NumberFormat:

Java
Скопировать код
NumberFormat format = NumberFormat.getInstance(Locale.FRANCE);
Number number = format.parse("10,9"); // Готовы к отсчёту!
double value = number.doubleValue();   // И мы запустились в орбиту double.

Преодолеваем языковой барьер

В мультиязычном приложении NumberFormat помогает справиться с разлиицами в локализации:

Java
Скопировать код
NumberFormat nf = NumberFormat.getNumberInstance(Locale.getDefault()); // Применяем локализацию по умолчанию
double number = nf.parse("123,45").doubleValue(); // Задача выполнена

Таким образом, мы учли и числовой формат, и локальные настройки пользователя.

Волшебство DecimalFormat и его символов

DecimalFormat и DecimalFormatSymbols позволят вам настроить формат чисел в любом нужном направлении:

Java
Скопировать код
DecimalFormatSymbols otherSymbols = new DecimalFormatSymbols();
otherSymbols.setDecimalSeparator(','); // Устанавливаем запятую в качестве десятичного разделителя
otherSymbols.setGroupingSeparator('.'); // Устанавливаем точку в качестве разделителя групп
DecimalFormat customFormat = new DecimalFormat("###,##0.00", otherSymbols);
double number = customFormat.parse("123.456,78").doubleValue();

Полезные материалы

Больше информации по теме можно найти в следующих ресурсах:

  1. DecimalFormat (Java Platform SE 7) — уточните, как использовать DecimalFormat для создания числовых форматов с запятой в роли десятичного разделителя.
  2. Customizing Formats (The Java™ Tutorials) — углубите знания о форматировании чисел с учётом локализации с помощью DecimalFormat.
  3. Лучший способ разбора строки с числом, где запятая выступает в роли десятичного разделителя? – Stack Overflow — обсуждения и ответы на вопросы по теме парсинга строк с числами, где запятая функционирует как разделитель.
  4. NumberFormat (Java Platform SE 8) — изучите NumberFormat для разбора и форматирования чисел в Java.
  5. Java DecimalFormat — примеры использования DecimalFormat и DecimalFormatSymbols.
  6. Руководство по NumberFormat в Java – Baeldung — детальное руководство Baeldung по применению NumberFormat.
  7. DecimalFormatSymbols (Java Platform SE 8) — настройка числовых форматов с помощью DecimalFormatSymbols для точного контроля над форматированием.