Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parse List<String> as JSON

I'm following the book Real-World Software Development and the current chapter was about writing a BankStatementCSVParser which reads a file like this:

30-01-2017,-100, Deliveroo
30-01-2017,-50, Tesco
01-02-2017,6000, Salary
02-02-2017,2000, Royalties
02-02-2017,-4000, Rent
03-02-2017,3000, Tesco
05-02-2017,-30, Cinema

and parses each line and outputs an object of this class:

public class BankTransaction {
    private final LocalDate date;
    private final double amount;
    private final String description;

    public BankTransaction(final LocalDate date, final double amount, 
           final String description) {
        this.date = date;
        this.amount = amount;
        this.description = description;
    }

    public LocalDate getDate() {
        return date;
    }

    public double getAmount() {
        return amount;
    }

    public String getDescription() {
        return description;
    }
}

This works fine and CSV was easy (especially since I was copying the book...), the problem came at the end of the chapter when I was asked to implement BankStatementJSONParser on my own if I could.

I've tried woth GSON and Jackson and I can't really get any example to work since my BankTransaction class is immutable and doesn't allow setters.

I managed to get one solution working but it's horrible to look at:

public List<BankTransaction> parseLinesFrom(List<String> lines) {
    Map<String, ?> map = new Gson().fromJson(String.join(" ", lines), Map.class);
    List<?> listOfTransactions = (List<?>) map.get("transactions");

    List<BankTransaction> bankTransactions = new ArrayList<>();
    listOfTransactions.forEach(rawJson -> {
        LinkedTreeMap<String, ?> javaJson = (LinkedTreeMap<String, ?>) rawJson;

        final LocalDate localDate = LocalDate.parse(javaJson.get("date").toString(), DATE_PATTERN);
        final double amount = Double.parseDouble(javaJson.get("amount").toString());
        final String description = javaJson.get("description").toString();
        BankTransaction newTransaction = new BankTransaction(localDate, amount, description);
        bankTransactions.add(newTransaction);
    });
    return bankTransactions;
}

Thankful for any insights how I can make this less ugly, maybe the problem is with my self-written .json file:

{
  "transactions": [
    {
      "date": "30-01-2017",
      "amount": -100,
      "description": "Deliveroo"
    },
    {
      "date": "01-02-2017",
      "amount": 6000,
      "description": "Salary"
    }
  ]
}
like image 241
Xenofono Avatar asked Sep 23 '26 03:09

Xenofono


1 Answers

There are some different solutions to your problem:

  1. You could create your own TypeAdapter to parse the List
  2. You could use TypeTokens to tell Gson at runtime what you will load (this will most certainly break the field date though)
  3. You could create your own JsonDeserializer

I personally would do the second one and create a custom TypeAdapter just for the LocalDate, which gets automatically applied by Gson after registering it.

like image 112
ThexXTURBOXx Avatar answered Sep 25 '26 16:09

ThexXTURBOXx



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!