javacollectionsjava-8java-stream

Find the total of a nested value from List<Obj> using Java 8 streams


Below is my JSON request. My requirement is to find total of the "cols"."value" field if "cols"."name"="tran_amt".

{
  "request" : {
    "reqID" : "6839796504132",
    "processID" : 97904250,
    "tables" : [ {
      "tableName" : "TABLE_NAME",
      "records" : [ {
        "recordID" : "record_id1",
        "cols" : [ {
          "name" : "tran_amt",
          "type" : "VARCHAR2",
          "value" : "562356"
        }, {
          "name" : "tran_id",
          "type" : "VARCHAR2",
          "value" : "123456"
        } ]
      }, {
        "recordID" : "record_id2",
        "cols" : [ {
          "name" : "tran_amt",
          "type" : "VARCHAR2",
          "value" : "987098"
        }, {
          "name" : "tran_id",
          "type" : "VARCHAR2",
          "value" : "123456"
        } ]
      } ]
    } ]
  }
}

Here is the solution I had tried:

cols = request.getTables().get(0).getRecords().get(0).getCols();
total = cols.stream().filter(o -> "tran_amt".equalsIgnoreCase(o.getName())).mapToInt(o -> Integer.valueOf(o.getValue())).sum();

My solution retrieves the "value" from the first obj of "cols" only (in this case 562356). It doesn't sum all "values" matching the criteria.

Any inputs on where I am wrong?


Solution

  • Try this:

    total = request.getTables()
                   .stream()
                   .flatMap(t -> t.getRecords().stream())
                   .flatMap(r -> r.getCols().stream())
                   .filter(c -> "tran_amt".equalsIgnoreCase(c.getName()))
                   .mapToInt(c -> Integer.valueOf(c.getValue()))
                   .sum();