Парсинг чисел с запятой в Java: альтернативы Double.valueOf()
Пройдите тест, узнайте какой профессии подходите
Быстрый ответ
Для преобразования строки с числом, где запятая выполняет функцию десятичного разделителя, в double
, используйте DecimalFormat
с DecimalFormatSymbols
, основываясь на локальном стандарте:
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 плюс символы локали позволит управлять ситуацией с запятой.
Непосредственное использование NumberFormat
Если требуется скорее обработать число, пробуйте NumberFormat
. Вот пример использования:
String numberStr = "123,456";
NumberFormat nf = NumberFormat.getInstance(Locale.FRANCE);
double number = nf.parse(numberStr).doubleValue(); // Итак, number равен 123.456 – вот так!
С использованием NumberFormat
, разбор проходит без проблем!
Быстрый и не изысканный способ
Если вам срочно требуется преобразовать строку в Double
, вы можете воспользоваться простой заменой:
String numberStr = "123,456";
double number = Double.parseDouble(numberStr.replace(',', '.')); // Производим замену запятой на точку!
Данный подход удобен и работает достаточно хорошо, однако, он не учитывает локаль, что может привести к проблемам!
При необходимости большей гибкости применяйте регулярные выражения
Регулярные выражения не всегда оптимальны, но они помогают, когда формат числа далек от стандарта:
String numberStr = "123,456";
numberStr = numberStr.replaceAll("([^\\d,]|(?<=\\d),(?=\\d{3}))+", "").replace(',', '.');
double number = Double.parseDouble(numberStr); // С регулярными выражениями всё под контролем!
Такой подход медленнее, чем String.replace()
, но необходим, когда локаль не указана.
Балансировка между различными локалями
Если ваш код должен грамотно работать с разнообразными локалями, NumberFormat
станет вашим спасением:
Locale userLocale = Locale.getDefault(); // Получаем локаль пользователя
DecimalFormatSymbols symbols = new DecimalFormatSymbols(userLocale); // Настраиваем символы под локаль
DecimalFormat format = new DecimalFormat("###,##0.00", symbols); // Формат теперь подстроен под локаль!
Визуализация
Процесс разбора числа с запятой можно вообразить как обратный отсчёт:
Обратный отсчёт с точкой: | 10.9.8.7.6.5.4.3.2.1 |
Теперь заменим точки на запятые:
Обратный отсчёт с запятой: | 10,9,8,7,6,5,4,3,2,1 |
Для успешного "запуска" (преобразования числа) необходимо преобразовать каждую запятую (,) в точку (.) :
🚀 --(Разбор)--> | 10.9.8.7.6.5.4.3.2.1 | --(Старт!)--> 🌙
Чтобы избежать ошибок при "запуске", используйте NumberFormat
:
NumberFormat format = NumberFormat.getInstance(Locale.FRANCE);
Number number = format.parse("10,9"); // Готовы к отсчёту!
double value = number.doubleValue(); // И мы запустились в орбиту double.
Преодолеваем языковой барьер
В мультиязычном приложении NumberFormat
помогает справиться с разлиицами в локализации:
NumberFormat nf = NumberFormat.getNumberInstance(Locale.getDefault()); // Применяем локализацию по умолчанию
double number = nf.parse("123,45").doubleValue(); // Задача выполнена
Таким образом, мы учли и числовой формат, и локальные настройки пользователя.
Волшебство DecimalFormat и его символов
DecimalFormat
и DecimalFormatSymbols
позволят вам настроить формат чисел в любом нужном направлении:
DecimalFormatSymbols otherSymbols = new DecimalFormatSymbols();
otherSymbols.setDecimalSeparator(','); // Устанавливаем запятую в качестве десятичного разделителя
otherSymbols.setGroupingSeparator('.'); // Устанавливаем точку в качестве разделителя групп
DecimalFormat customFormat = new DecimalFormat("###,##0.00", otherSymbols);
double number = customFormat.parse("123.456,78").doubleValue();
Полезные материалы
Больше информации по теме можно найти в следующих ресурсах:
- DecimalFormat (Java Platform SE 7) — уточните, как использовать
DecimalFormat
для создания числовых форматов с запятой в роли десятичного разделителя. - Customizing Formats (The Java™ Tutorials) — углубите знания о форматировании чисел с учётом локализации с помощью
DecimalFormat
. - Лучший способ разбора строки с числом, где запятая выступает в роли десятичного разделителя? – Stack Overflow — обсуждения и ответы на вопросы по теме парсинга строк с числами, где запятая функционирует как разделитель.
- NumberFormat (Java Platform SE 8) — изучите
NumberFormat
для разбора и форматирования чисел в Java. - Java DecimalFormat — примеры использования
DecimalFormat
иDecimalFormatSymbols
. - Руководство по NumberFormat в Java – Baeldung — детальное руководство Baeldung по применению
NumberFormat
. - DecimalFormatSymbols (Java Platform SE 8) — настройка числовых форматов с помощью
DecimalFormatSymbols
для точного контроля над форматированием.