map.forEach Unexpected return value

2

I have the following map:

private static Map<ParseCreator, Parseable> map = new HashMap<>();

I run this map as follows:

for (Map.Entry<ParseCreator, Parseable> entry : map.entrySet()) {
        ParseCreator creator = entry.getKey();
        Parseable parseable = entry.getValue();

        if (parseable.canParse(reader)) {
            return creator.create(reader.getText());
        }
    }

But if I use forEach of Java 8 I get the following error:

map.forEach((k,v) -> {
            ParseCreator creator = k;
            Parseable parseable = v;

            if (parseable.canParse(reader)) {
                return creator.create(reader.getText()); //Erro: Unexpected return value
            }
        });

How do I use forEach correctly in this case?

    
asked by anonymous 09.05.2018 / 13:52

1 answer

2

You can create a stream with the Entry of this map, filter the ones you want, and then map them to the type returned by create :

Optional<Tipo> result = map
    // obtem um stream com todos Entry do map
    .entrySet().stream()
    // considerar apenas as entradas em que canParse retorna true
    .filter(e -> e.getValue().canParse(reader))
    // chamar o create(reader.getText())
    .map(e -> e.getKey().create(reader.getText()))
    // pegar o primeiro resultado
    .findFirst();

Since Tipo is the type returned by the create method - as you have not been informed, I am leaving a generic "any" name, but you only need to change the type you are using.

Another detail is that this code returns a Optional , that is, it might not find any results, and the advantage of Optional is that you can choose what to do if it has no results.

For example, you can simply return the value:

return result.get();

But if filter has not found an entry that satisfies the condition (in this case, for none of them canParse returned true ), Optional will not have a value and get() will throw NoSuchElementException .

Alternatively, you can set a default value to be returned if the Optional is of no value:

return result.orElse(valorDefault);

Being valorDefault is any value you want to return, if none is found by filter (can be even null ).

Or you can choose to throw an exception (other than NoSuchElementException ):

return result.orElseThrow(RuntimeException::new);

And if you need to pass arguments to the Exception constructor:

return result.orElseThrow(() -> new RuntimeException(argumentos))

Anyway, with Optional you can choose which action to take if you have not found any value. View the documentation for all options.

    
09.05.2018 / 18:54