Home > Enterprise >  How to Iterate through List of Map<Object,Long>
How to Iterate through List of Map<Object,Long>

Time:10-31

I want to get values from this List:

List<Map<CategoryModel,Long>> list = categoryRespository.findSalesByCategory();

I print values ​​from list like this:

for (Map<CategoryModel, Long> categoryModelLongMap : list) {
    System.out.println(categoryModelLongMap.values());
}

Output:

[computers, 0]
[mouses, 0]
[keyboards, 0]
[laptops, 0]

But now i want to add these values to another map, as they appear above. I wrote something like that but it doesnt work

    Map<String, String> newMap = new HashMap<>();

    for (Map<CategoryModel, Long> featureService : list) {
        for (Map.Entry<CategoryModel,Long> entry : featureService.entrySet()) {
            newMap.put(String.valueOf(entry.getKey()), String.valueOf(entry.getValue()));
        }
    }

Output:

{number=0, category_name=laptops}

Map<String, String> newMap, should be Map<String, Long>, but i dont know how to dispose of those "number" and "category_name". Objecy CategoryModel have also method "getCategoryName" which return String. Can someone help me how can i iterate through values in list?

CodePudding user response:

One way to do it would be using something like this:

Instead of

    Map<String, String> newMap = new HashMap<>();

for (Map<CategoryModel, Long> featureService : list) {
    for (Map.Entry<CategoryModel,Long> entry : featureService.entrySet()) {
        newMap.put(String.valueOf(entry.getKey()), String.valueOf(entry.getValue()));
    }
}

Use

    Map<String, String> newMap = new HashMap<>();
                    
                        for (Map<CategoryModel, Long> featureService : list) {
                            for (Map.Entry<CategoryModel,Long> entry : featureService.entrySet()) {
                    String rawKeyReturn = String.valueOf(entry.getKey());            
                    String rawValueReturn = String.valueOf(entry.getValue());   
                newMap.put(
        rawKeyReturn.substring(rawKeyReturn.indexOf("=") 1,rawKeyReturn.length()), 
                
rawValueReturn.substring(rawValueReturn.indexOf("=") 1,rawValueReturn.length())
                );
         }           
  }

Apologies for the formatting, I am not sure how to fix the spacing in the code blocks.

This solution works by finding just creating a substring of the results of your calls to the valueOf() method and cutting off the label (everything up to and including the first = sign).

There may be more elegant ways to do this, but I'm not sure how.

CodePudding user response:

You need to flatten the entries of each map in the List.

And then group the data associated with each distinct CategoryModel and add up the values mapped to the same key.

Basically, this can be done using two nested loops (your attempt was close).

That how it can be implemented using Java 8 method Map.merge():

List<Map<CategoryModel,Long>> list = categoryRespository.findSalesByCategory();
    
Map<String, Long> result = new HashMap<>();

for (Map<CategoryModel, Long> categoryModelLongMap : list) {
    for (Map.Entry<CategoryModel, Long> entry : categoryModelLongMap.entrySet()) {
        result.merge(entry.getKey().getCategoryName(),
                     entry.getValue(),
                     Long::sum);
    }
}

Alternatively, it can be done using Stream API.

groupingBy summingLong

List<Map<CategoryModel,Long>> list = categoryRespository.findSalesByCategory();
    
Map<String, Long> result = list.stream()
    .flatMap(map -> map.entrySet().stream())
    .collect(Collectors.groupingBy(
        entry -> entry.getKey().getCategoryName(),
        Collectors.summingLong(Map.Entry::getValue)
    ));

toMap

List<Map<CategoryModel,Long>> list = categoryRespository.findSalesByCategory();
    
Map<String, Long> result = list.stream()
    .flatMap(map -> map.entrySet().stream())
    .collect(Collectors.toMap(
        entry -> entry.getKey().getCategoryName(),
        Map.Entry::getValue,
        Long::sum
    ));
  • Related