Question: Any way to perform the below code using Java 8.

```
        final Map<String, Collection<ProductStrAttributeOverrideRulesModel>> attributeRulesMap = new HashMap<String, Collection<ProductStrAttributeOverrideRulesModel>>();
        for (final ProductStrAttributeOverrideRulesModel rule : rules)
        {
            final String key = rule.getProductStrAttributeOverride().getProductStrTypeField().getAttributeDescriptorQualifier();
            if (attributeRulesMap.containsKey(key))
            {
                final Collection<ProductStrAttributeOverrideRulesModel> currentRules = attributeRulesMap.get(key);
                currentRules.add(rule);
            }
            else
            {
                final Collection<ProductStrAttributeOverrideRulesModel> list = new LinkedList<ProductStrAttributeOverrideRulesModel>();
                list.add(rule);
                attributeRulesMap.put(key, list);
            }
        }

```

if it is only 

```
 final Map<String, ProductStrAttributeOverrideRulesModel> attributeRulesMap

```

than i can do like following but i need to arrange the whole collection inside a map based on key and each key can have multiple values stored in collection.

```
Map<String, ProductStrAttributeOverrideRulesModel> result =
choices.stream().collect(Collectors.toMap(ProductStrAttributeOverrideRulesModel::getProductStrAttributeOverride.getProductStrTypeField.getAttributeDescriptorQualifier,
                                          Function.identity()));

```

Answer: 
You could use `groupingBy` :

```
Map<String,List<ProductStrAttributeOverrideRulesModel>>
    map = 
        choices.stream()
               .collect(Collectors.groupingBy(rule -> rule.getProductStrAttributeOverride().getProductStrTypeField().getAttributeDescriptorQualifier()));

```

And if you don't want a `List`, you can pass a second argument to `groupingBy` and specify whatever `Collection` you want. For example :

```
Map<String,Collection<ProductStrAttributeOverrideRulesModel>>
    map =
        choices.stream()
               .collect(Collectors.groupingBy(rule -> rule.getProductStrAttributeOverride().getProductStrTypeField().getAttributeDescriptorQualifier(),
                                              Collectors.toCollection(HashSet::new)));

```
Note that it doesn’t always have to be a `Stream` operation. Your code would also benefit from using the “diamond operator” (though not new to Java 8) and from using new collection operations, i.e. `computeIfAbsent`, which allows to elide the entire conditional inside the loop and its code duplication. Putting both together, you’ll get:

```
final Map<String, Collection<ProductStrAttributeOverrideRulesModel>>
                                                   attributeRulesMap = new HashMap<>();
for(final ProductStrAttributeOverrideRulesModel rule: rules)
{
    final String key = rule.getProductStrAttributeOverride()
        .getProductStrTypeField().getAttributeDescriptorQualifier();
    attributeRulesMap.computeIfAbsent(key, x->new LinkedList<>()).add(rule);
}

```

You could also replace the loop by a `forEach` invocation, if you wish:

```
rules.forEach(rule -> attributeRulesMap.computeIfAbsent(
    rule.getProductStrAttributeOverride()
        .getProductStrTypeField().getAttributeDescriptorQualifier(),
    x->new LinkedList<>()).add(rule)
);

```

though it’s debatable whether this is an improvement over the classical loop here…