Home > database >  How to call function inside .map() using Streams in Java
How to call function inside .map() using Streams in Java

Time:10-06

I am using java.util.Locale to get a list of countries.

I have a code that looks like this:

 List<Country> countries = new ArrayList<>();

        String[] countryCodes = Locale.getISOCountries();

        for (String countryCode : countryCodes) {
            Locale locale = new Locale(language, countryCode);
            String code = locale.getCountry();
            String name = locale.getDisplayCountry(locale);

            try {
                countries.add(new Country(code, name));
            } catch (IllegalArgumentException e) {
                // code and name not valid for creating country. ignore
            }
        }

        return countries;
    }

And it works fine. I would like to convert this code that I have in using Java Streams.

I have started like this:

return Stream.of(Locale.getISOCountries())
                .map(countryCode -> new Locale(language, countryCode))
                .map(c-> new Country(c.getCountry(), c.getDisplayCountry()))
                .filter(c-> !(c.getCode().equals("")) && !(c.getName().equals("")))
                .collect(Collectors.toList());

But instead of this line of code

.map(c-> new Country(c.getCountry(), c.getDisplayCountry()))

I would like to call this function:

private Optional<Country> createCountry(Locale locale) {
        try {
            return Optional.of(new Country(locale.getCountry(), locale.getDisplayCountry(locale)));
        } catch (IllegalArgumentException e) {
            return Optional.empty();
        }

I was thinking in doing something like this:

.map(createCountry(locale))

But function and local are not recognized.

What am I missing?

CodePudding user response:

The map method accepts a Function while you are providing it with the result of the method invocation, which is an Optional<Country>. You need to pass in the method reference instead:

List<Country> countries = Stream.of(Locale.getISOCountries())
            .map(countryCode -> new Locale(language, countryCode))
            .map(this::createCountry)
            .filter(Optional::isPresent)
            .map(Optional::get)
            .filter(c -> !(c.getCode().equals("")) && !(c.getName().equals("")))
            .collect(Collectors.toList());

Note the additional steps to map the Optional to a Country if present.

  • Related