Home > Software engineering >  Create a Map<Key,Object> based on a List<Object> - Converting Loops into Java streams
Create a Map<Key,Object> based on a List<Object> - Converting Loops into Java streams

Time:06-11

Facing error while converting a List<Object> to a HashMap<Key,Object>.

I can do with a traditional code, but I'm getting an error while doing using Java 8 streams and ignore the duplicate keys.

Equivalent code:

Map<String, Field> uniqueFields = new HashMap<>();
for (Field field : allFields) {
    uniqueFields.put(field.getName(), field);
}

Tried below stream, but there's a syntactic mistake:

Map<String, Field> uniqueFields1 = allFields.stream()
    .collect(Collectors.toMap(
        Field::getName, 
        (oldValue, newValue) -> oldValue));

CodePudding user response:

You just need one more argument to the toMap function to tell the collector what should be the values of the Map. You can use Function.identity(), which means it will just pass the Field right through.

 Map<String,Field> uniqueFields = allFields.stream()
    .collect(Collectors.toMap(Field::getName, Function.identity(), 
        (oldValue,newValue) -> oldValue));

CodePudding user response:

The flavor of Collectors.toMap(), that expects two arguments, should be provided with Functions: keyMapper and valueMapper (that are responsible for expracting a key and a value respectivelly from a stream element).

But in your code snippet, the second argument isn't of type Function, because you've provided two arguments oldValue, newValue, but Function takes only one.

You need to use a version of toMap that in addition to keyMapper and valueMapper functions expects the third argument BinaryOperator mergeFunction which is meant to resolve values mapped to the same key:

Map<String, Field> uniqueFields = allFields.stream()
    .collect(Collectors.toMap(
        Field::getName,      // generating a kay
        Function.identity(), // generating a value
        (oldValue, newValue) -> oldValue))); // resolving duplicates
  • Related