2016-10-04 6 views
1

В моем коде Java у меня есть четыре числа в текстовом формате (String): Es.Общий способ преобразования String в Big Decimal

String s1 = "1234.56"; 
String s2 = "1235,56"; 
String s3 = "1,234.56"; 
String s4 = "1.234,56"; 

Я хочу, чтобы преобразовать эти строки в BigDecimal:

BigDecimal b1 = new BigDecimal(s1); 
... 
... 

Очевидно, что это не работает, потому что BigDecimal не принимает все форматы (строки с запятыми). Существует общий способ, который позволяет мне преобразовывать все строки в BigDecimal?

ответ

0

Что относительно DecimalFormat? Doc here

Вы просто должны определить шаблон для десятичного разделителя перед разбором строки ...

DecimalFormat decimalFormat = new DecimalFormat("#,###.##"); 
decimalFormat.setParseBigDecimal(true); 
BigDecimal bigDecimal = (BigDecimal) decimalFormat.parse("1,234.56"); 
System.out.println(bigDecimal); 

следует сделать трюк

+0

Хорошо, но на самом деле я не знаю формат строк «n». use case: У меня есть массив строк, и мне нужно преобразовать. – fuerteVentura22

+0

Если у вас нет шаблона, вы ничего не сможете разобрать. Как сделать разницу между «1,234,56» и «1.234,56» без шаблона? – BenB

+0

Если вы знаете, что всегда есть 2 десятичных знака, вы можете выбрать десятичный разделитель, чтобы построить шаблон, который я думаю .... – BenB

1

Десятичная часть всегда находится локали зависит, так что вы можете использовать NumberFormat класса и использовать проанализированный результат в виде строки, чтобы получить от него BigDecimal

Пример:

final NumberFormat format = NumberFormat.getInstance(Locale.FRANCE); 
final Number number = format.parse("3,1415"); 
final BigDecimal bd = new BigDecimal(number.toString()); 
System.out.println(bd); 
+0

Поскольку 'format.parse' [будет возвращать двойной] (http: // docs .oracle.com/javase/8/docs/api/java/text/NumberFormat.html # parse-java.lang.String-java.text.ParsePosition-), это будет страдать от той же проблемы, что и [BigDecimal (double) constructor] (http://docs.oracle.com/javase/8/docs/api/java/math/BigDecimal.html#BigDecimal-double-): Неточные значения, которые не соответствуют входной строке. – VGR

+0

для строки "s3" print 1.234 – fuerteVentura22

+0

yes и 1.234 - допустимый вход для Bigdecimal –

0

Чтобы охватить все случаи я хотел бы предложить следующее осуще:

private static BigDecimal convertToBigDecimal(String s) { 
    StringBuilder sb = new StringBuilder(); 

    if (s.indexOf('.') != -1 && s.indexOf(',') != -1) { 
     s = s.replace(',', '.'); 
     String[] ss = s.split("\\."); 
     for (int i = 0; i < ss.length; i++) { 
      if (i > 0 && i == ss.length - 1) { 
       sb.append('.'); 
      } 
      sb.append(ss[i]); 
     } 
    } else if (s.indexOf('.') != -1) { 
     String[] ss = s.split("\\."); 
     if (ss.length > 2) { 
      sb.append(s.replace(".", "")); 
     } else { 
      // assume it is decimal delimiter 
      sb.append(ss[0]).append('.').append(ss[1]); 
     } 
    } else if (s.indexOf(',') != -1) { 
     String[] ss = s.split(","); 
     if (ss.length > 2) { 
      sb.append(s.replace(",", "")); 
     } else { 
      // assume it is decimal delimiter 
      sb.append(ss[0]).append('.').append(ss[1]); 
     } 
    } 

    BigDecimal bd = new BigDecimal(sb.toString()); 
    return bd; 
} 

Идеи является первым проверить, если у нас есть и чем мы определенно должны дробная часть и заменит все , на ., а затем пропустить все . кроме последний. В противном случае, если у нас есть несколько одинаковых разделителей, это число без десятичной части. В другом случае нам нужно знать шаблон, чтобы отличить его от десятичного или нет. Для выборочных чисел мы предполагаем, что это с десятичной точкой.

+0

Для «1,234,567» (без десятичной части) результат будет неправильным ... (1234.567) Но это лучший снимок до сих пор ... – BenB

+0

Вы правы @BenB. Невозможно различать, не знаю шаблона для случая 111,222, будь то 1112222 или 111,222. –