[java] 쉼표로 소수점을 구분하는 가장 좋은 방법은?

다음과 같은 결과가 발생합니다 Exception.

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

구문 분석하는 더 좋은 방법이 있나요 "1,234"얻을 1.234이상이 : p = p.replaceAll(",",".");?



답변

java.text.NumberFormat을 사용하십시오 .

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


답변

이것을 사용할 수 있습니다 (프랑스어 로케일에는 ,소수점 구분 기호가 있습니다)

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


답변

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


답변

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


답변

물론 올바른 로케일을 사용해야합니다. 질문이 도움 될 것입니다.