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;
}

Nikolas Charalambidis
  • 40,893
  • 16
  • 117
  • 183
Alex Man
  • 4,746
  • 17
  • 93
  • 178

1 Answers1

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>.

Nikolas Charalambidis
  • 40,893
  • 16
  • 117
  • 183
  • 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 – Alex Man May 16 '19 at 06:38
  • 1
    If you provide an alternative `List` in case the `availableDomains` are `null`, then replace `.orElse(Collections.emptyList())` with your alternative `List`, 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` :) – Nikolas Charalambidis May 16 '19 at 07:53
  • 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 – Alex Man May 16 '19 at 08:12
  • 1
    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`](https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html) package and try to implement the functional interfaces (see [`@FunctionalInterface`](https://docs.oracle.com/javase/8/docs/api/java/lang/FunctionalInterface.html)) and creating own ones. – Nikolas Charalambidis May 16 '19 at 08:23
  • Do you have any idea on this [issue](https://stackoverflow.com/questions/56327888/java8-lambda-for-checking-two-conditions) – Alex Man May 27 '19 at 14:35
  • @AlexMan: See my answer there. – Nikolas Charalambidis May 27 '19 at 21:28
  • Hi Nikolas, as per your suggestion I am learning the lambda function by practicing with some sample examples....I have posted one more question on the same for lambda function converstion. Can you please take a look at that also. https://stackoverflow.com/questions/56333011/converting-array-iteration-to-lambda-function-using-java8 – Alex Man May 27 '19 at 22:24