I have written this lambda that is..
You didn't write just a lambda, but a chain of methods using lambda expressions. one if them is code -> keyMap.put(code, messageKeyRegistry).
Back to your question. You start with the iteration correctly (from the EnumSet), the next step is to realize what happens in the forEach methods.
- Extract codes from the set of keys using them as keys using
messageKeyRegistry
- Using the extractor as a value
messageKeyRegistry.
This is a job for map, however since the data structure is more complicated (collection in a collection), then flatMap would serve better. Finally, you'd result with something like:
Map<MessageKey, MessageKeyRegistry> keyMap = EnumSet.allOf(MessageKeyRegistry.class)
.stream()
.flatMap(messageKeyRegistry -> messageKeyRegistry.getCodeToMessage().keySet()
.stream()
.map(code -> new AbstractMap.SimpleEntry<>(code, messageKeyRegistry)))
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));
However, what you do has a drawback. I see the keys are overridden since there cannot be duplicates which is visible from the original solution, i.e. from this line that iterates at least once which implies the key may be overridden:
.forEach(code -> keyMap.put(code, messageKeyRegistry))
So what I suggest is rather group mapping using Collectors.groupingBy resulting in Map<MessageKey, List<MessageKeyRegistry>>:
Map<MessageKey, List<MessageKeyRegistry>> keyMap = EnumSet.allOf(MessageKeyRegistry.class)
.stream()
.flatMap(messageKeyRegistry -> messageKeyRegistry.getCodeToMessage().keySet()
.stream()
.map(code -> new AbstractMap.SimpleEntry<>(code, messageKeyRegistry)))
.collect(Collectors.groupingBy(Entry::getKey));
For immutable map, if you mean a map that is read-only use the Collections.unmodifiableMap() wrapper:
Map<MessageKey, List<MessageKeyRegistry>> unmodifiableKeyMap = Collections.unmodifiableMap(keyMap);
MessageKeyRegistrystructure.