Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Remove all entries where value is an empty Optional from map

I want to remove all entries where value is an empty Optional from the map. It would seem that nothing complicated, but I am trying to find a better solution that I have.


Input:

I have the following Map:

Map<String, Function<String, Optional<String>>> attributesToCalculate = new HashMap<>();

Where key - just a String and value - reference to method which returns Optional < String >


Output:

As a result, I want to get

Map<String, String> calculatedAttributes

(excluding entries where value was an empty Optional)


Here is my solution

      return attributesToCalculate.entrySet()
        .stream()
        .map(entry -> Pair.of(entry.getKey(), entry.getValue().apply(someString)))
        .filter(entry -> entry.getValue().isPresent())
        .collect(Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue().get()));

But I don't like the .filter part because then I have to invoke .get() on Optional in collect part.

Is there а better way (maybe without .get invocation) to solve this problem? Thanks.

like image 916
Yevhenii Semenov Avatar asked Oct 31 '17 22:10

Yevhenii Semenov


People also ask

How do I remove all entries from maps?

HashMap. clear() method in Java is used to clear and remove all of the elements or mappings from a specified HashMap. Parameters: The method does not accept any parameters. Return Value: The method does not return any value.

What does Optional get return if empty?

The empty method of the Optional method is used to get the empty instance of the Optional class. The returned object doesn't have any value.

Can optional map return null?

The class invariant is that an Optional can never hold a null value, so either the map should fail or it should return an empty Optional .


1 Answers

Not a very pretty one, and similar to for-loop:

 return attributesToCalculate.entrySet().stream().collect(HashMap::new, (sink, entry) -> {

    entry.getValue().apply(someString).ifPresent(v -> sink.put(entry.getKey(), v));

}, Map::putAll);
like image 93
Adam Kotwasinski Avatar answered Oct 23 '22 20:10

Adam Kotwasinski