如何使用Java8流根据map param返回的列表进行过滤

如何使用Java8流根据map param返回的列表进行过滤,java,java-8,java-stream,Java,Java 8,Java Stream,我尝试使用Java流根据特定条件过滤一些值。我可以使用传统的for循环和一些流来实现相同的功能,但是我想在流中完全重写相同的逻辑 原始代码: public List <String> getProductNames(Hub hub, String requestedGroup) { List <SupportedProduct> configuredProducts = repo.getSupportedProducts(hub); List <

我尝试使用Java流根据特定条件过滤一些值。我可以使用传统的for循环和一些流来实现相同的功能,但是我想在流中完全重写相同的逻辑

原始代码:

public List <String> getProductNames(Hub hub, String requestedGroup) {

    List <SupportedProduct> configuredProducts = repo.getSupportedProducts(hub);

    List <String> productNames = new ArrayList <> ();

    for (SupportedProduct supportedProduct: configuredProducts) {
        List < String > categoryNameList = new ArrayList <> ();
        String activeCategoryName = supportedProduct.getCategoryDetails().getActiveCategoryName();
        if (activeCategoryName == null) {
            Optional.ofNullable(supportedProduct.getCategoryDetails().getCategories())
                .orElse(Collections.emptyList())
                .forEach(category - > categoryNameList.add(category.getName()));
        } else {
            categoryNameList.add(activeCategoryName);
        }
        for (String catName: categoryNameList) {
            Division division = divisionRepo.getDivisionByCatName(catName);
            if (division != null && division.getGroup() == requestedGroup) {
                productNames.add(supportedProduct.getProductName());
            }
        }
    }

    return productNames;

}
return Optional.ofNullable(configuredProducts).orElse(Collections.emptyList()).stream()
                .map(supportedProduct -> {
                    List<String> categoryNameList = new ArrayList<>();

                    String activeCategoryName = supportedProduct.getCategoryDetails().getActiveCategoryName();

                    if (activeCategoryName == null) {
                        Optional.ofNullable(supportedProduct.getCategoryDetails().getCategories())
                                .orElse(Collections.emptyList())
                                .forEach(category -> categoryNameList.add(category.getName()));
                    } else {
                        categoryNameList.add(activeCategoryName);
                    }
                    return categoryNameList;
                })
                .filter(catName ->{
                    Division division = divisionRepo.getDivisionByCatName(catName);
                    return division != null && division.getGroup() == requestedGroup;
                })........
公共列表getProductNames(集线器集线器、字符串请求组){
列表configuredProducts=repo.getSupportedProducts(集线器);
List productNames=new ArrayList();
对于(支持的产品支持的产品:配置的产品){
ListcategoryNameList=newarraylist();
字符串activeCategoryName=supportedProduct.getCategoryDetails().getActiveCategoryName();
如果(activeCategoryName==null){
可选.ofNullable(supportedProduct.getCategoryDetails().getCategories())
.orElse(Collections.emptyList())
.forEach(category->categoryNameList.add(category.getName());
}否则{
添加(activeCategoryName);
}
用于(字符串catName:categoryNameList){
分部分部=分部报告。getDivisionByCatName(catName);
if(division!=null&&division.getGroup()==requestedGroup){
productNames.add(supportedProduct.getProductName());
}
}
}
返回产品名称;
}
我的尝试:

public List <String> getProductNames(Hub hub, String requestedGroup) {

    List <SupportedProduct> configuredProducts = repo.getSupportedProducts(hub);

    List <String> productNames = new ArrayList <> ();

    for (SupportedProduct supportedProduct: configuredProducts) {
        List < String > categoryNameList = new ArrayList <> ();
        String activeCategoryName = supportedProduct.getCategoryDetails().getActiveCategoryName();
        if (activeCategoryName == null) {
            Optional.ofNullable(supportedProduct.getCategoryDetails().getCategories())
                .orElse(Collections.emptyList())
                .forEach(category - > categoryNameList.add(category.getName()));
        } else {
            categoryNameList.add(activeCategoryName);
        }
        for (String catName: categoryNameList) {
            Division division = divisionRepo.getDivisionByCatName(catName);
            if (division != null && division.getGroup() == requestedGroup) {
                productNames.add(supportedProduct.getProductName());
            }
        }
    }

    return productNames;

}
return Optional.ofNullable(configuredProducts).orElse(Collections.emptyList()).stream()
                .map(supportedProduct -> {
                    List<String> categoryNameList = new ArrayList<>();

                    String activeCategoryName = supportedProduct.getCategoryDetails().getActiveCategoryName();

                    if (activeCategoryName == null) {
                        Optional.ofNullable(supportedProduct.getCategoryDetails().getCategories())
                                .orElse(Collections.emptyList())
                                .forEach(category -> categoryNameList.add(category.getName()));
                    } else {
                        categoryNameList.add(activeCategoryName);
                    }
                    return categoryNameList;
                })
                .filter(catName ->{
                    Division division = divisionRepo.getDivisionByCatName(catName);
                    return division != null && division.getGroup() == requestedGroup;
                })........
返回可选的.ofNullable(configuredProducts).orElse(Collections.emptyList()).stream()
.map(支持的产品->{
List categoryNameList=新建ArrayList();
字符串activeCategoryName=supportedProduct.getCategoryDetails().getActiveCategoryName();
如果(activeCategoryName==null){
可选.ofNullable(supportedProduct.getCategoryDetails().getCategories())
.orElse(Collections.emptyList())
.forEach(category->categoryNameList.add(category.getName());
}否则{
添加(activeCategoryName);
}
返回类别名称列表;
})
.filter(catName->{
分部分部=分部报告。getDivisionByCatName(catName);
返回division!=null&&division.getGroup()==requestedGroup;
})........
但除此之外,我迷路了

请帮我写同样使用流


编辑:添加了用于测试的IDEOne-

内部逻辑相当复杂,但是,请尝试以下方法:

public List <String> getProductNames(Hub hub, String requestedGroup) {
    List<SupportedProduct> configuredProducts = repo.getSupportedProducts(hub);

    // extract pairs: 
    //    key=SupportedProduct::getProductName
    //    values=List with one activeCategoryName OR names of all the categories
    Map<String, List<String>> namedActiveCategoryNamesMap = configuredProducts.stream()
        .collect(Collectors.toMap(
                SupportedProduct::getProductName,
                p -> Optional.ofNullable(p.getCategoryDetails().getActiveCategoryName())
                        .map(Collections::singletonList)
                        .orElse(Optional.ofNullable(p.getCategoryDetails().getCategories())
                                        .stream()
                                        .flatMap(Collection::stream)
                                        .map(Category::getName)
                                        .collect(Collectors.toList()))));

    // look-up based on the categories' names, group equality comparison and returning a List
    return namedActiveCategoryNamesMap.entrySet().stream()
        .filter(entry -> entry.getValue().stream()
                .map(catName -> divisionRepo.getDivisionByCatName(catName))
                .filter(Objects::nonNull)
                .map(Division::getGroup)
                .anyMatch(requestedGroup::equals))
        .map(Map.Entry::getKey)
        .collect(Collectors.toList());
}
私有函数productNamesFunction(字符串请求组){
返回map->map.entrySet().stream()
.filter(entry->entry.getValue().stream())
.map(divisionRepo::getDivisionByCatName)
.filter(对象::非空)
.map(部门::getGroup)
.anyMatch(requestedGroup::equals))
.map(map.Entry::getKey)
.collect(Collectors.toList());
}
private Function categoryNamesFunction(){
返回p->Optional.ofNullable(p.getCategoryDetails().getActiveCategoryName())
.map(集合::单音列表)
.orElse(可选的.ofNullable(p.getCategoryDetails().getCategories())
.stream()
.flatMap(集合::流)
.map(类别::getName)
.collect(Collectors.toList());
}

哇,这太棒了。谢谢你。我将学习并尝试这一点。(我从未在任何地方见过流被这样使用:))我没有测试过代码,只要我不知道类的结构,也没有数据可以测试。这个答案的目的是让您了解如何使用Java流API解决这个问题。不过,您可能需要自定义/修复/编辑某些部分。没问题。我只需要一个起点,你的回答很有帮助。将在一个小时后测试解决方案(刚刚离开)并返回报告。仅尝试了此解决方案,
toMap
调用中列表上的
.stream()
调用似乎无法作为
可选选项工作。ofNullable
不会返回流。我正在尝试为您的测试准备一个IDEone片段
private Function<SupportedProduct, List<String>> categoryNamesFunction() {
    return p -> Optional.ofNullable(p.getCategoryDetails().getActiveCategoryName())
            .map(Collections::singletonList)
            .orElse(Optional.ofNullable(p.getCategoryDetails().getCategories())
                    .stream()
                    .flatMap(Collection::stream)
                    .map(Category::getName)
                    .collect(Collectors.toList()));
}