首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何用java8 stream api改写代码?

如何用java8 stream api改写代码?
EN

Stack Overflow用户
提问于 2018-06-02 06:14:20
回答 2查看 95关注 0票数 3

我正在学习Java 8,我想用java Stream重写常用的java代码。好让它做得更好。我的代码:

代码语言:javascript
复制
public Set<Product> getProductsByFilter(Map<String, List<String>>filterParams) {

    Set<Product> productsByBrand = new HashSet<Product>();
    Set<Product> productsByCategory = new HashSet<Product>();
    Set<String> criterias = filterParams.keySet();
    if (criterias.contains("brand")) {
        for (String brandName : filterParams.get("brand")) {
            for (Product product : listOfProducts) {
                if (brandName.equalsIgnoreCase(product.
                        getManufacturer())) {
                    productsByBrand.add(product);
                }
            }
        }
    }

    if (criterias.contains("category")) {
        for (String category : filterParams.get("category")) {
            productsByCategory.addAll(this.
                    getProductsByCategory(category));
        }
    }
    productsByCategory.retainAll(productsByBrand);
    return productsByCategory;
}

我不知道如何校正if (criterias.contains("brand"))中的重新格式化代码。

EN

回答 2

Stack Overflow用户

发布于 2018-06-02 06:35:47

如果代码可以工作,为什么要更改它呢?然而,这里有一个使用流API的解决方案:

代码语言:javascript
复制
public Set<Product> getProductsByFilter(Map<String, List<String>> filterParams) {

    Set<Product> productsByBrand = filterParams.containsKey("brand") ?
                filterParams.get("brand")
                         .stream()
                         .flatMap(brandName -> listOfProducts.stream()
                                            .filter(product -> brandName.equalsIgnoreCase(product.getManufacturer())))
                         .collect(Collectors.toCollection(HashSet::new)) : new HashSet<>();

   Set<Product> productsByCategory =
            filterParams.containsKey("category") ?
                  filterParams.get("category")
                               .stream()
                               .flatMap(category -> this.getProductsByCategory(category).stream())
                               .collect(Collectors.toCollection(HashSet::new)) : new HashSet<>();

        productsByCategory.retainAll(productsByBrand);
        return productsByCategory;
}

或者正如@shmosel所建议的那样,您可以使用getOrDefault来避免使用三元运算符

代码语言:javascript
复制
Set<Product> productsByBrand = 
       filterParams.getOrDefault("brand", Collections.emptyList())
                   .stream()
                   .flatMap(brandName -> listOfProducts.stream()
                              .filter(product -> brandName.equalsIgnoreCase(product.getManufacturer())))
                   .collect(Collectors.toCollection(HashSet::new));

Set<Product> productsByCategory =
      filterParams.getOrDefault("category", Collections.emptyList())
                  .stream()
                  .flatMap(category -> this.getProductsByCategory(category).stream())
                  .collect(Collectors.toCollection(HashSet::new));
票数 2
EN

Stack Overflow用户

发布于 2018-06-02 07:28:27

这里试图让它尽可能地基于lambda-stream。

首先,如果忽略任何一个条件(品牌或类别),则当前问题代码将返回一个空集。如果这不是bug,而是预期的行为,那么检查是否是这种情况并快速返回空集是很有意义的。因此,代码可以像这样开始:

代码语言:javascript
复制
final List<String> filterBrands = filterParams.getOrDefault("brand", Collections.emptyList()));
final List<String> filterCategories = filterParams.getOrDefault("categories", Collections.emptyList()));
if (filterCategories.isEmpty() || filterCategories.isEmpty()) {
  return Collections.emptySet();
}

如果第一个列表是空的,您可以避免组成第二个列表,但它添加了几行代码,并且增益很可能是超级可以忽略的。

对于这一点,您可以使用另一种答案方法,即创建两个标准产品集,然后使用交集。然而,由于您可以直接从产品访问品牌,也就是制造商,因此有一种替代方案不需要明确地实例化这样的集合,因此我们可能会提高性能,这取决于返回大小与每个标准集合的比率。所以如果结果只是几个产品...比方说5,但每个标准或其中一个标准集可能最终只有1000秒,这样做可以节省内存或cpu:

代码语言:javascript
复制
final Set<String> manufacturers = filterBrands.stream()
        .map(String::toLowerCase)
        .collect(Collectors.toSet());

return filterCategories.stream()
    .flatMap(this::getProductsByCategory)
    .distinct() // optional but might be better performance 
                // if categories share products.
    .filter(product -> manufacturers.contains(product.getManufacturer().toLowerCase()))
    .collect(Collectors.toSet());
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50651580

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档