Skip to content
Advertisement

How do i make use of groupingby in java

I have a movie list from a web service that i need to group using genres attribute from the data. My question is very similar to this groupby ngFor angular2 but in java instead.

movie list from the web service looks like this

[
    {
        "title": "AAAAAAAA",
        "genres": [
          "Comedy"
        ]
    },
    {
        "title": "BBBBBBBBBBBB",
        "genres": [
          "Action", "Adventure"
        ]
    },
    {
        "title": "CCCCCCCCCCCCC",
        "genres": [
          "Action"
        ]
    },
    {
        "title": "DDDDDDDDDDDD",
        "genres": [
          "Comedy", "Adventure"
        ]
    },
    {
        "title": "EEEEEEEEEEEEEEEEEEE",
        "genres": [
          "Horror"
        ]
    }
]

here is what i’m trying to achieve but i cant seems to get it right

[
    {
        "Action": [
            {
                "title": "BBBBBBBBBBBB",
                "genres": [
                  "Action", "Adventure"
                ]
            },
            {
                "title": "CCCCCCCCCCCCC",
                "genres": [
                  "Action"
                ]
            }
        ],
        "Adventure": [
            {
                "title": "BBBBBBBBBBBB",
                "genres": [
                  "Action", "Adventure"
                ]
            },
            {
                "title": "DDDDDDDDDDDD",
                "genres": [
                  "Comedy", "Adventure"
                ]
            }
        ],
        "Comedy": [
            {
                "title": "AAAAAAAA",
                "genres": [
                  "Comedy"
                ]
            },
            {
                "title": "DDDDDDDDDDDD",
                "genres": [
                  "Comedy", "Adventure"
                ]
            }
        ],
        "Horror": [
            {
                "title": "EEEEEEEEEEEEEEEEEEE",
                "genres": [
                  "Horror"
                ]
            }
        ]
    }
]

i’ve tried replicating the javascript solution from the answer in groupby ngFor angular2 but I’m stucked

    ItemArray.stream().reduce((identity, accumulator) -> {    
        accumulator.getGenres().forEach((k) -> {});
        return identity;
    });

Advertisement

Answer

I think it would be easier not to use streams:

Map<String, List<Item>> itemsByGenre = new HashMap<>();
for (Item item : items) {
  for (String genre : item.genres()) {
    itemsByGenre.computeIfAbsent(genre, g -> new ArrayList<>()).add(item);
  }
}

The key point here is that you need to explode by genre, because each item can be in multiple genres. So, you could do something like this:

Map<String, List<Item>> itemsByGentre = items.stream()
    // Make a stream of map entries where the key is the genre, and the value is the item.
    .flatMap(i -> i.genres().stream().map(g -> new AbstractMap.SimpleEntry<>(g, i))
    .collect(
        // Now, group by key (genre)...
        Collectors.groupingBy(
            Map.Entry::getKey,
            // and map the entry to just the value (the item),
            // and collect the items into a list.
            Collectors.mapping(Map.Entry::getValue, Collectors.toList())));
User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement