Это пример кода, который я придумал, есть ли лучший способ сделать это без использования каких-либо внешних банок. Метод convertStringToDouble является основным методом преобразования. Также ограничение десятичного значения до 2 цифр после точки.

import java.text.DecimalFormat;

public class ExampleCode {

    private final static String ROUND_DECIMAL_VALUE = "#.##";

    public static void main(String[] args) {

    String s = "1 1/2";

      Double dd =  convertStringToDouble(s);
        System.out.println("***Final converted value***" +dd);
    }


    /**
     * Convert the String dose value to Double
     *
     * @param dose
     * @return finalDoseVal
     */
    private static Double convertStringToDouble(String dose) {

        Double finalDoseVal = null;

        if(dose != null && !dose.isEmpty()) {
            if (dose.contains("/")) {

                String[] splitStr = dose.split(" ");

                DecimalFormat df2 = new DecimalFormat(ROUND_DECIMAL_VALUE);

                if (splitStr.length == 2) {

                    String wholeNum = splitStr[0];
                    String fractionValue = splitStr[1];

                    Double fractionValToDouble = parseFractionalValue(fractionValue);

                    finalDoseVal = Double.sum(Double.valueOf(wholeNum), Double.valueOf(df2.format(fractionValToDouble)));

                } else if (splitStr.length == 1) {
                    String numOrFractionValue = splitStr[0];
                    Double d;
                    if (numOrFractionValue.contains("/")) {
                        d = Double.valueOf(df2.format(parseFractionalValue(numOrFractionValue)));
                    } else {
                        d = Double.valueOf(numOrFractionValue);
                    }
                    finalDoseVal = d;
                }
            }
            else {
                if(dose != null && !dose.isEmpty()) {
                    finalDoseVal = Double.valueOf(dose);
                }
            }
        }
        return finalDoseVal;
    }

Это метод, который преобразует дробное значение String в десятичное.

/**
 * Convert fractional String value to decimal value
 * e.g "1/2" converted to 0.5
 *
 * @param ratio
 * @return Double
 */
public static double parseFractionalValue(String ratio) {
    if (ratio.contains("/")) {
        String[] rat = ratio.split("/");
        return Double.parseDouble(rat[0]) / Double.parseDouble(rat[1]);
    } else {
        return Double.parseDouble(ratio);
    }
}
0
user1883465 24 Апр 2020 в 07:01
Вы написали в своем вопросе: ограничение десятичного значения до 2 цифр после точки См. метод printf, как в System.out.printf(%.2f", dd)
 – 
Abra
24 Апр 2020 в 07:23

1 ответ

Не забудьте добавить туда отделку, чтобы пробелы по краям не заставляли его переворачиваться. Во всяком случае, это довольно просто в целом. Вам просто нужно разделить его дважды, один раз для косой черты и один раз для пробела. Как только вы это сделаете, вы просто проанализируете их, а затем для округления я предпочитаю использовать функцию округления. Если вы умножите на 100 внутри функции округления и разделите на 100 вне ее, это даст вам два десятичных знака.

private static double StringtoDouble(String dose){

  if(dose!=null&&dose.length()>0){
    if(dose.contains("/")){
      String[] inter = dose.trim().split("/");
      if(inter[0].contains(" ")){
        String[] inter2 = inter[0].split(" ");
        return (double)round((Float.parseFloat(inter2[0])+Float.parseFloat(inter2[1])/Float.parseFloat(inter[1]))*100)/100;
      } else {
        return (double)floor((Float.parseFloat(inter[0])/Float.parseFloat(inter[1]))*100)/100;
      }
    } else {
      return (double)floor((Float.parseFloat(dose))*100)/100;
    }
  } else { 
    return 0;
  }
}
1
Cadyn Bombaci 24 Апр 2020 в 07:26
Если dose равно, например, "1/", то inter будет содержать только один элемент. Следовательно, inter[1] выдаст ArrayIndexOutOfBoundsException
 – 
Abra
24 Апр 2020 в 07:31
Спасибо за ваше наблюдение. Я не особо собирался писать метод, который мог бы обрабатывать все возможные входные данные и избегать ошибок времени выполнения. Если исходному плакату необходимо обработать большое количество различных текстов, которые могут содержать ошибки, такие как та, о которой вы упомянули, то, вероятно, им следует просто отложить блок try, catch.
 – 
Cadyn Bombaci
24 Апр 2020 в 07:36
Базовое хорошее программирование. А именно, проверьте правильность параметров метода и обработайте пограничные случаи. Я предполагаю, что OP будет использовать ваш код как есть, так почему бы не приложить дополнительные усилия для обеспечения надежного кода?
 – 
Abra
24 Апр 2020 в 07:44