【问题标题】:Converting country domain functionality to Java8 Lambda将国家域功能转换为 Java8 Lambda
【发布时间】:2019-10-03 02:06:37
【问题描述】:

我有以下代码,它根据我从 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;
}

我正在尝试将上述代码转换为 Java8 Lambda 函数,到目前为止我已转换的代码如下所示,但它不正确

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

我无法为 Lambda 带来完整的转换,因为我特别想为

引入 lambda 函数
if(availableCountry.getName().equals(availableDomain.getCountry()))

谁能帮我解决这个问题?

我的完整源代码如下所示

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

【问题讨论】:

    标签: java arraylist lambda java-8 java-stream


    【解决方案1】:

    这可能有效:

    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>
    

    orElse(Collections.emptyList()) 行确保整个Stream 产生一个空的List&lt;Domain&gt;,因为如果与空的List&lt;Domain&gt; 相比,没有Country 是合格的。

    【讨论】:

    • 感谢您的回答。假设我想返回一个默认值,如果我们找不到任何默认值,就说 List。我们怎样才能做到这一点
    • 如果您提供替代List&lt;Domain&gt;,以防availableDomainsnull,则将.orElse(Collections.emptyList()) 替换为您的替代List&lt;Domain&gt;,例如.orElse(alternativeList)。如果您想要默认的Domain,而Country 的名称与可用域集合中的任何名称都不匹配,则将orElse(null) 替换为您的默认Domain,例如orElse(new CustomDomain())。我不明白您的要求,但是,我希望我涵盖了能够使用 Optional 的所有必要条件:)
    • 你能给我举个例子吗...你能告诉我我们如何在 lambda 函数方面有专长吗...你有什么学习资料可以推荐
    • 可以找到很多。学习它们的最好方法是练习。我个人是通过在这里回答问题来学习它们的。从探索java.util.function 包开始,尝试实现功能接口(参见@FunctionalInterface)并创建自己的接口。
    • 你对这个issue有什么想法
    猜你喜欢
    • 2016-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多