Чтение определенного столбца из CSV и преобразование в double для дальнейших вычислений на Java

У меня есть файл CSV (фиксированные 43 столбца и строки меняются каждый раз), который содержит в нем значения String и double. Мне нужно получить значения из 12-го (NetPrice) и 13-го (налог) столбцов, которые на самом деле являются двойными значениями. Мне нужно добавить (NetPrice + Tax) в каждую строку до конца файла CSV и получить общую сумму. Я могу получить значения в формате String, но при попытке преобразовать в double я сталкиваюсь с NumberFormatExeption. Я понял, что есть какая-то ошибка при конвертации, но не могу ее идентифицировать. Просьба о помощи по тому же. Ниже мой код.

Я нашел одно решение для аналогичной проблемы в SO, но это мне не помогло, поэтому отправляю свой вопрос.

Пример файла CSV

Чтение определенного столбца из CSV и преобразование в double для дальнейших вычислений на Java

В конце мне нужно снова добавить всю добавленную выше сумму, чтобы получить окончательную общую цену, как показано на изображении выше.

public void getTotalPrice () выбрасывает IOException {

    String csvFile = "file path";
    String line ;
    String cvsSplitBy = ",";
    String NetPrice;
    String Tax;
    double FinalTotal = 0.00;

    try (BufferedReader br = new BufferedReader(new FileReader(csvFile))) 
    {
        br.readLine();
        while ((line = br.readLine()) != null) 
        {
            String[] Amount = line.split(cvsSplitBy);
            NetPrice = Amount[11]; //hold 12th column value
            Tax = Amount[12]; //hold 13th column value
            double NP = Double.parseDouble(NetPrice); //convert String to double
            double T = Double.parseDouble(Tax); //convert string to double
            FinalTotal = FinalTotal + (NP+T); //calculation for getting final price
        }

    }catch(NumberFormatException n)
    {
        n.printStackTrace();
    }
}

Ниже приведена ошибка, с которой я столкнулся:

java.lang.NumberFormatException: For input string: ""78.63""

Из сообщения об ошибке я понял, что строковое значение, которое пытается преобразовать в double, читается с дополнительными двойными кавычками "" ""

почему вы пытаетесь создать собственный синтаксический анализатор csv, есть много существующих решений, которые делают это, плюс еще многое другое. Раньше я использовал super-csv.github.io/super-csv/index.html и ни разу не пожалел о своем решении.

Prateek Jain 01.05.2018 16:44

Прикомандированный. commons.apache.org/proper/commons-csv - еще один вариант.

user3456014 01.05.2018 22:38
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
2
345
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вам необходимо удалить цитаты из String, прежде чем анализировать его как число. Я бы также рекомендовал использовать объект BigDecimal при работе с числовыми значениями, такими как валюта, как в вашем случае.

Код

  public static void main(String[] args) throws IOException {

    String csvFile = "file path";
    String line;
    String cvsSplitBy = ",";
    String netPrice;
    String tax;
    BigDecimal finalTotal = BigDecimal.ZERO;

    try (BufferedReader br = new BufferedReader(new FileReader(csvFile))) {
        br.readLine();
        while ((line = br.readLine()) != null) {
            String[] Amount = line.split(cvsSplitBy);

            netPrice = Amount[11]; //hold 12th column value
            netPrice = netPrice.replace("\"", "");
            BigDecimal netPriceBd = new BigDecimal(netPrice);

            tax = Amount[12]; //hold 13th column value
            tax = tax.replace("\"", "");
            BigDecimal taxBd = new BigDecimal(tax);

            BigDecimal total = netPriceBd.add(taxBd);

            finalTotal = finalTotal.add(total);
        }

    } catch (NumberFormatException n) {
        n.printStackTrace();
    }
}

Большое спасибо Гаррету .... Это сработало. Я узнал о BigDecimal сегодня, спасибо и за это.

rvsk 02.05.2018 07:12

Рад, что помог. Можете ли вы принять ответ, если он вас устраивает.

Garreth Golding 02.05.2018 14:48

Поскольку Tax - это строка, вы можете применить к ней метод, который проверяет, не является ли она нулевым, а затем удаляет кавычки (и, в конечном итоге, другие нечисловые символы), а затем анализирует его до двойного. Что-то в этом роде:

private static double convertToDouble(String str) {
    if (str == null || str.trim().isEmpty()) {
        return 0.0;
    }
    return Double.parseDouble(str.replaceAll("[^\\d\\.]", ""));
}

Вы можете быстро протестировать этот метод, используя этот код здесь:

public static void main(String[] args) throws Throwable {

    System.out.println(convertToDouble("\"78.63\""));
    System.out.println(convertToDouble("\"7.63\"  "));
    System.out.println(convertToDouble(null));
    System.out.println(convertToDouble("    "));
    System.out.println(convertToDouble(" 2.123"));
}

Это распечатает:

78.63
7.63
0.0
0.0
2.123

Большое спасибо, Гил, у меня это сработало. Но в середине вычисления десятичные разряды суммы внезапно увеличиваются до 13 цифр, а для следующего вычисления она автоматически уменьшается до 2 знаков после запятой. И, наконец, общая сумма с 13 знаками после запятой отображается как 4033,5799999999995 (которую я могу уменьшить до 2 знаков после запятой, используя функцию округления)

rvsk 02.05.2018 07:25

@rvsk Если это было полезно для вас, вы можете принять этот ответ. Это повысит вашу репутацию.

gil.fernandes 02.05.2018 08:35

Другие вопросы по теме