Search code examples
javajava-8stream

Get Count of json key using Java Stream


I have a json object that looks like this

 [{
                "startAt": 1617605301292,
                "endAt": 1617605317095,
                "duration": 15803,
                "selection": {
                    "selected.Speed": "0",
                    "selected.Low": "65535",
                    "selected.Fast": "7173",
                    "selected.medium": "5"
                },
                "details": {
                    "phase": [{
                        "value": "2",
                        "timestamp": 1617605301316
                    }]
                }
            },
            {
                "startAt": 1617603849697,
                "endAt": 1617603966378,
                "duration": 116681,
                "selection": {
                    "selected.Speed": "0",
                    "selected.Low": "65535",
                    "selected.Fast": "123",
                    "selected.medium": "5"
                },
                "details": {
                    "phase": [{
                        "value": "2",
                        "timestamp": 1617603849749
                    }]
                }
            }
        ]

I need to count how many times selected.Fast has occurred. I am trying with stream and this is what I have written so far

List<Map<String, Object>> jsonObj = mapper.readValue(jArr, new TypeReference<List<Map<String, Object>>>(){});
                
Map<String, Long> counted = jsonObj.stream()
        .map(x -> x.get("selection").toString() )
        .collect(Collectors.toList())
        .stream()
        .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));

System.out.println(counted.toString());

            

But I am getting count of all the key inside selection object, and I want count for specific Json key which is selected.Fast For Example selected.Fast:"7173" -> occurred - 5times selected.Fast:"123" -> occurred - 2times

Any help would be appreciated.


Solution

  • Can you check if this is what you are looking for ?

     List<JsonNode> jsonObj = mapper.readValue(jArr, new TypeReference<List<JsonNode>>() {
        });
    
        Map<String, Long> counted = jsonObj.stream()
                .map(x -> {
                    String selection = x.get("selection").get("selected.Fast").asText();
                    return "selected.Fast:" + selection;
                }).collect(Collectors.toList())
                .stream()
                .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
    
        System.out.println(counted); //{selected.Fast:123=1, selected.Fast:7173=1}
    

    Edit: Without converting to JsonNode

        List<Map<String, Object>> jsonObj = mapper.readValue(jArr, new TypeReference<List<Map<String, Object>>>(){});
    
        Map<String, Long> counted = jsonObj.stream()
                .map(x -> {
                    String selection = ((Map<String,Object>)x.get("selection")).get("selected.Fast").toString();
                    return "selected.Fast:" + selection;
                }).collect(Collectors.toList())
                .stream()
                .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
    
        System.out.println(counted);
    

    Edit 2: Solution to get count of all the elements inside the selection

        Map<String, Long> counted = jsonObj.stream().flatMap(x -> {
            JsonNode selection = x.get("selection");
            return StreamSupport.stream(Spliterators.spliteratorUnknownSize(selection.fields(), 0), false);
        })
                .map(x -> x.getKey() + ":" + x.getValue()).collect(Collectors.toList())
                .stream()
                .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
        System.out.println(counted);