2010-12-01 2 views
107

Ниже приводит к Exception:Лучший способ parseDouble с запятой в качестве десятичного разделителя?

String p="1,234"; 
Double d=Double.valueOf(p); 
System.out.println(d); 

Есть ли лучший способ разбора "1,234" получить 1.234 чем: p = p.replaceAll(",",".");?

+14

В моем опыте, replaceAll(), как вы предложили, является лучшим способом сделать это. Это не зависит от текущей локали, это просто, и это работает. – 2010-12-01 11:07:37

+0

@JoonasPulakka Ваше предложение работает только в том случае, если текущий локаль по умолчанию использует точку в качестве разделителя десятичных чисел. Правильно ? – 2016-12-24 00:36:12

+1

@Marco Altieri: `replaceAll (", ",". ")` Заменяет все запятые точками. Если запятых нет, значит, ничего не делает. `Double.valueOf()` работает (только) со строками, которые используют точку в качестве десятичного разделителя. Текущая локализация по умолчанию здесь не влияет. https://docs.oracle.com/javase/8/docs/api/java/lang/Double.html#valueOf-java.lang.String- – 2016-12-27 19:38:10

ответ

152

Используйте java.text.NumberFormat:

NumberFormat format = NumberFormat.getInstance(Locale.FRANCE); 
    Number number = format.parse("1,234"); 
    double d = number.doubleValue(); 
50

Вы можете использовать это (французская локаль имеет , для десятичного разделителя)

NumberFormat nf = NumberFormat.getInstance(Locale.FRANCE); 
nf.parse(p); 

Или вы можете использовать java.text.DecimalFormat и установить соответствующие символы:

DecimalFormat df = new DecimalFormat(); 
DecimalFormatSymbols symbols = new DecimalFormatSymbols(); 
symbols.setDecimalSeparator(','); 
symbols.setGroupingSeparator(' '); 
df.setDecimalFormatSymbols(symbols); 
df.parse(p); 
1

Конечно, вам необходимо использовать правильный язык. This вопрос поможет.

15

Как указывает E-Riz, NumberFormat.parse (String) анализирует «1,23abc» как 1.23. Для того, чтобы весь вход можно использовать:

public double parseDecimal(String input) throws ParseException{ 
    NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.getDefault()); 
    ParsePosition parsePosition = new ParsePosition(0); 
    Number number = numberFormat.parse(input, parsePosition); 

    if(parsePosition.getIndex() != input.length()){ 
    throw new ParseException("Invalid input", parsePosition.getIndex()); 
    } 

    return number.doubleValue(); 
} 
3

Это статический метод, который я использую в своем собственном коде:

public static double sGetDecimalStringAnyLocaleAsDouble (String value) { 

    if (value == null) { 
     Log.e("CORE", "Null value!"); 
     return 0.0; 
    } 

    Locale theLocale = Locale.getDefault(); 
    NumberFormat numberFormat = DecimalFormat.getInstance(theLocale); 
    Number theNumber; 
    try { 
     theNumber = numberFormat.parse(value); 
     return theNumber.doubleValue(); 
    } catch (ParseException e) { 
     // The string value might be either 99.99 or 99,99, depending on Locale. 
     // We can deal with this safely, by forcing to be a point for the decimal separator, and then using Double.valueOf ... 
     //http://stackoverflow.com/questions/4323599/best-way-to-parsedouble-with-comma-as-decimal-separator 
     String valueWithDot = value.replaceAll(",","."); 

     try { 
      return Double.valueOf(valueWithDot); 
     } catch (NumberFormatException e2) { 
      // This happens if we're trying (say) to parse a string that isn't a number, as though it were a number! 
      // If this happens, it should only be due to application logic problems. 
      // In this case, the safest thing to do is return 0, having first fired-off a log warning. 
      Log.w("CORE", "Warning: Value is not a number" + value); 
      return 0.0; 
     } 
    } 
} 
4

Если вы не знаете правильный Locale и строка может иметь замостить это может быть последним средством:

doubleStrIn = doubleStrIn.replaceAll("[^\\d,\\.]++", ""); 
    if (doubleStrIn.matches(".+\\.\\d+,\\d+$")) 
     return Double.parseDouble(doubleStrIn.replaceAll("\\.", "").replaceAll(",", ".")); 
    if (doubleStrIn.matches(".+,\\d+\\.\\d+$")) 
     return Double.parseDouble(doubleStrIn.replaceAll(",", "")); 
    return Double.parseDouble(doubleStrIn.replaceAll(",", ".")); 

Имейте в виду: это будет счастливо разбора строк, как «R 1 52.43,2» на «15243,2».

-3

Это будет делать работу:

Double.parseDouble(p.replace(',','.')); 
3
Double.parseDouble(p.replace(',','.')) 

... очень быстро, как он ищет базовый массив символов на основе углеродно по-гольца. Строка, заменяющая версии, компилирует RegEx для оценки.

В основном заменить (char, char) примерно в 10 раз быстрее, и поскольку вы будете делать такие вещи в низкоуровневом коде, имеет смысл подумать об этом. Оптимизатор Hot Spot не поймет этого ... Конечно, в моей системе нет.