用逗号作为小数分隔符的parseDouble的最佳方法是什么?

时间:2010-12-01 10:59:20

标签: java

以下是Exception

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

是否有更好的方法来解析"1,234"以获取1.234而不是:p = p.replaceAll(",",".");

10 个答案:

答案 0 :(得分:186)

使用java.text.NumberFormat

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

答案 1 :(得分:59)

您可以使用此(法语区域设置,用于小数点分隔符)

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

答案 2 :(得分:17)

正如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 :(得分:5)

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

...非常快,因为它以char-by-char为基础搜索基础字符数组。字符串替换版本编译RegEx以进行评估。

基本上替换(char,char)大约快10倍,因为你将在低级代码中做这些事情,所以考虑这个是有意义的。热点优化器不会弄明白......当然不在我的系统上。

答案 4 :(得分: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”。

答案 5 :(得分: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;
        }
    }
}

答案 6 :(得分:1)

您当然需要使用正确的区域设置。 This问题会有所帮助。

答案 7 :(得分:0)

如果您不知道接收到的字符串值的语言环境,并且该语言环境不一定与当前的默认语言环境相同,则可以使用以下方法:

private static double parseDouble(String price){
    String parsedStringDouble;
    if (price.contains(",") && price.contains(".")){
        int indexOfComma = price.indexOf(",");
        int indexOfDot = price.indexOf(".");
        String beforeDigitSeparator;
        String afterDigitSeparator;
        if (indexOfComma < indexOfDot){
            String[] splittedNumber = price.split("\\.");
            beforeDigitSeparator = splittedNumber[0];
            afterDigitSeparator = splittedNumber[1];
        }
        else {
            String[] splittedNumber = price.split(",");
            beforeDigitSeparator = splittedNumber[0];
            afterDigitSeparator = splittedNumber[1];
        }
        beforeDigitSeparator = beforeDigitSeparator.replace(",", "").replace(".", "");
        parsedStringDouble = beforeDigitSeparator+"."+afterDigitSeparator;
    }
    else {
        parsedStringDouble = price.replace(",", "");
    }

    return Double.parseDouble(parsedStringDouble);

}

无论字符串的语言环境是什么,它都会返回一个double值。而且无论有多少逗号或要点。因此,传递1,000,000.54会起作用,1.000.000,54也会起作用,因此您不必再依赖默认语言环境来解析字符串。该代码没有得到最佳优化,因此欢迎您提出任何建议。我试图测试大多数情况,以确保它可以解决问题,但是我不确定它是否涵盖所有问题。如果您发现突破性的价值,请告诉我。

答案 8 :(得分:0)

在Kotlin中,您可以使用以下扩展名:

msg

,您可以在代码中的任何地方使用它,如下所示:

fun String.toDoubleEx() : Double {
   val decimalSymbol = DecimalFormatSymbols.getInstance().decimalSeparator
  return if (decimalSymbol == ',') {
      this.replace(decimalSymbol, '.').toDouble()
  } else {
      this.toDouble()
  }
}

简单而通用!

答案 9 :(得分:-4)

这可以胜任:

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