java parsedouble_关于java:使用逗号作为小数点分隔符的parseDouble的最佳方法?

以下是Exception的结果:

String p="1,234";

Double d=Double.valueOf(p);

System.out.println(d);

与p = p.replaceAll(",",".");相比,有没有更好的方法解析"1,234"以获取1.234?

以我的经验,如您所建议,replaceAll()是执行此操作的最佳方法。它不依赖于当前语言环境,它很简单,并且可以正常工作。

@JoonasPulakka,仅当当前默认语言环境使用点作为小数点分隔符时,您的建议才有效。对 ?

@Marco Altieri:replaceAll(",",".")用点替换所有逗号。如果没有逗号,则不执行任何操作。 Double.valueOf()(仅)适用于使用点作为小数点分隔符的字符串。当前的默认语言环境不会影响此处的任何内容。 docs.oracle.com/javase/8/docs/api/java/lang/

replaceAll(",",".")的唯一问题是,它只有在有一个逗号的情况下才起作用:即:1,234,567将抛出java.lang.NumberFormatException: multiple points。正向查找的正则表达式足以满足p.replaceAll(",(?=[0-9]+,)","").replaceAll(",",".")的需求,网址为:regular-expressions.info/lookaround.html

没有问题。 NumberFormatException是好的。您怎么知道哪个逗号是正确的?格式错误,您所能做的就是向用户显示比异常情况更好的可读性消息。

@TheincredibleJan不,格式没有错误。一些语言环境使用逗号作为千位分隔符,因此您可以在数字中使用多个逗号,并且从技术上讲,它仍然是有效的输入。

使用java.text.NumberFormat:

NumberFormat format = NumberFormat.getInstance(Locale.FRANCE);

Number number = format.parse("1,234");

double d = number.doubleValue();

仅当当前的默认语言环境恰好使用逗号作为小数点分隔符时,此方法才有效。

为了进一步解决问题,某些语言环境使用逗号作为千位分隔符,在这种情况下," 1,234"将解析为1234.0而不是抛出错误。

一些欧洲语言环境(例如FRANCE,德国和意大利)使用逗号作为小数点分隔符,因此您可以显式使用它们,而不必依赖默认值。

NumberFormat的问题在于它将静默忽略无效字符。因此,如果您尝试解析" 1,23abc",它将很高兴地返回1.23,而没有向您指示传入的String包含不可解析的字符。在某些情况下,这实际上可能是理想的,但我认为通常它不是理想的行为。

对于TURKEY,您应该使用NumberFormat.getInstance(new Locale(tr_TR))

Java是否使用十进制作为默认值来处理数字?这就是为什么它失败了吗?

有关谁使用哪种分隔符的信息,请参见en.wikipedia.org/w/

当小数点分隔符是点(。)时,它将以旧的方式转换。例如2110.0转换为21100

您可以使用它(法语语言环境的小数点分隔符为,)

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.222.222,33)将转换为" 1 222 222,33",这不是我想要的。那谢谢啦!

另一件事是,西班牙语言环境未列为"默认值",并且我无法使用new Locale("es","ES")构造具有正确格式的Locale,然后自动使用NumberFormat(以,作为小数点分隔符和< x4>作为千位分隔符,只有DecimalFormat起作用。

为什么不是所有国家都在那里?我对使用法语语言环境设置波兰数字格式感到奇怪...

正如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();

}

此处详细说明了该策略:ibm.com/developerworks/library/j-numberformat

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

...非常快,因为它逐个字符地搜索基础字符数组。字符串替换版本会编译RegEx进行评估。

基本上,replace(char,char)大约快10倍,并且由于您将在低级代码中执行这些操作,因此考虑一下是有意义的。热点优化器无法解决问题……当然不在我的系统上。

如果您不知道正确的语言环境,并且字符串可以有千位分隔符,那么这可能是最后的选择:

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"。

这是我在自己的代码中使用的静态方法:

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;

}

}

}

如果默认的语言环境是类似德语的逗号分隔的小数点,该怎么办?您可以传入例如" 1,000,000",它不会解析为德语语言环境,然后将其替换为" 1.000.000",这不是有效的Double。

@jimmycar,您好,Ive刚刚更新了我的答案,以使用当前版本的静态方法。希望这能解决您的问题!皮特

您当然需要使用正确的语言环境。这个问题会有所帮助。

这将完成工作:

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

如果您认为replace与使用replaceAll明显不同,那么最初的问题是:"是否有比" p = p.replaceAll(",","。");更好的方法来解析" 1,234"以获取1.234。 ,请说明原因。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值