2

I have the following code that gets all the domains list based on incoming countries details which I get from a REST API

private static List<Domain> testDataInPlain() {
    List<Domain> allDomains = new ArrayList<>();
    List<Country> countries = buildIncomingCountries();
    List<Country> availableCountries = availableCountries();

    for (Country availableCountry : availableCountries) {
        if(countries.contains(availableCountry)) {
            List<Domain> availableDomains = getBusinessCountryDomains(availableCountry);
            if(availableDomains == null) {
                return new ArrayList<>();
            } else {
                for (Domain availableDomain : availableDomains) {
                    if(availableCountry.getName().equals(availableDomain.getCountry())) {
                        allDomains.add(availableDomain);
                    }
                }
            }
        }
    }
    return allDomains;
}

I am trying to convert the above code to Java8 Lambda function, The code which I have converted so far is shown below but it is not correct

private static List<?> testDataInLambda() {
    List<Domain> allDomains = new ArrayList<>();
    List<Country> countries = buildIncomingCountries();
    List<Country> availableCountries = availableCountries();

    return availableCountries.stream()
            .filter(countries::contains)
            .map(country -> {
                List<Domain> availableDomains = getBusinessCountryDomains(country);
                return availableDomains;
            })
            .filter(allDomains::contains)
            .collect(Collectors.toList());
}

I am not able to bring the complete conversion to Lambda since I am stucked especially on bringing lambda function for

if(availableCountry.getName().equals(availableDomain.getCountry()))

Can anyone please help me with this?

My full source code is shown below

package com.example.demo;

import lombok.AllArgsConstructor;
import lombok.Data;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class Test {
    public static void main(String[] args) {
        System.out.println(testDataInPlain());
        System.out.println(testDataInLambda());
    }

    private static List<Domain> testDataInPlain() {
        List<Domain> allDomains = new ArrayList<>();
        List<Country> countries = buildIncomingCountries();
        List<Country> availableCountries = availableCountries();

        for (Country availableCountry : availableCountries) {
            if(countries.contains(availableCountry)) {
                List<Domain> availableDomains = getBusinessCountryDomains(availableCountry);
                if(availableDomains == null) {
                    return new ArrayList<>();
                } else {
                    for (Domain availableDomain : availableDomains) {
                        if(availableCountry.getName().equals(availableDomain.getCountry())) {
                            allDomains.add(availableDomain);
                        }
                    }
                }
            }
        }
        return allDomains;
    }

    private static List<?> testDataInLambda() {
        List<Domain> allDomains = new ArrayList<>();
        List<Country> countries = buildIncomingCountries();
        List<Country> availableCountries = availableCountries();

        return availableCountries.stream()
                .filter(countries::contains)
                .map(country -> {
                    List<Domain> availableDomains = getBusinessCountryDomains(country);
                    return availableDomains;
                })
                .filter(allDomains::contains)
                .collect(Collectors.toList());
    }

    private static List<Country> buildIncomingCountries() {
        // I am mocking the below details
        List<Country> countries = new ArrayList<>();
        countries.add(new Country("IND",1));
        countries.add(new Country("USA",2));
        countries.add(new Country("GER",3));
        return countries;
    }

    private static List<Country> availableCountries() {
        // I am mocking the below details
        List<Country> countries = new ArrayList<>();
        countries.add(new Country("IND",1));
        countries.add(new Country("KEN",2));
        countries.add(new Country("GER",3));
        countries.add(new Country("FRA",4));
        countries.add(new Country("JPN",5));
        countries.add(new Country("CHN",6));
        countries.add(new Country("UAE",7));
        countries.add(new Country("IRE",8));
        return countries;
    }

    private static List<Domain> getBusinessCountryDomains(Country country) {
        // I am mocking the below details based on the country
        List<Domain> domains = new ArrayList<>();
        domains.add(new Domain(".in","IND"));
        domains.add(new Domain(".zim","ZIM"));
        domains.add(new Domain(".den","DEN"));
        domains.add(new Domain(".fra","FRA"));
        return domains;
    }
}

@Data
@AllArgsConstructor
class Country {
    private String name;
    private Integer code;
}

@Data
@AllArgsConstructor
class Domain {
    private String name;
    private String country;
}

1 Answer 1

4

This might work:

availableCountries.stream()
    .filter(availableCountries::contains)       // Stream<Country> of qualified countries
    .map(country -> Optional                    // attempt to map each Cuntry to Domain
        .ofNullable(availableDomains)           // Optional<List<Domain>>
        .orElse(Collections.emptyList())        // or else an empty List
        .stream()
        .filter(availableDomain -> availableDomain.getName().equals(country.getCountry()))
        .findAny()
        .orElse(null))                          // if the name doesn't match, then null
    .filter(Objects::nonNull)                   // filter the nulls out
    .collect(Collectors.toList());              // and produce a List<Domain>

The line orElse(Collections.emptyList()) assures the entire Stream produces an empty List<Domain> since no Country would be qualified if compared to an empty List<Domain>.

Sign up to request clarification or add additional context in comments.

7 Comments

thanks for the answer. Lets say if I want to return a default value say List with the default value if we could not find any. how can we do that
If you provide an alternative List<Domain> in case the availableDomains are null, then replace .orElse(Collections.emptyList()) with your alternative List<Domain>, such as .orElse(alternativeList). In case you want a default Domain when a Country's name doesn't match with any from the collection of the available domain, then replace orElse(null) with your default Domain, such as orElse(new CustomDomain()). I don't get what do you ask for, however, I hope I covered all the necessary to be able to work with Optional :)
can you give me an example...also can you tell me how we can expertise in lambda functions....do you have any learning material to recommend
There could be found many. The best way to learn them is to practice. I personally learned them by answering questions here. Start with exploring the java.util.function package and try to implement the functional interfaces (see @FunctionalInterface) and creating own ones.
Do you have any idea on this issue
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.