How to filter Map values using a Set of Strings?

Marco Marchetti :

I had to filter Map values using a Set of strings, I could make it work (a partner suggested to use anyMatch() in place of what I'm doing here, but I can't see how) and I wanted to know what do you think of this algorithm and if it is possible to improve it, maybe using another Stream function or even the contains() method, also I'm not sure if I can avoid iterating directly through the Set (for each loop).

ProductsResponse serviceResponse = (obtained from backend) ...;
Set<String> productIds = (some code to collect the strings from another API) ...;
//Here starts the filtering process 
serviceResponse.setProducts(serviceResponse.getProducts().entrySet().stream()
          .filter(product -> {
             for (String productId: productIds) {
                if (product.getKey().startsWith(productId)) {
                    return true;
                }
             }
             return false;
           }).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)));

Important note: I'm using the Set to filter the products in the Map, the strings that are in the Set have almost the same format as the keys of the Map, so it is safe to compare them using the startsWith()

Update 1: adding the involved classes definition.

class ProductsResponse() {

  private Map<String, ProductResource> products;
}

class ProductResource () {

   private String productId;
   private String name;
   private Double price;
}
Andronicus :

You can avoid inner for-loop by streaming through the set and using anyMatch:

serviceResponse.setProducts(serviceResponse.getProducts()
    .entrySet().stream()
    .filter(product -> productIds.stream().anyMatch(productId -> product.getKey().startsWith(productId)))
    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)));

You can also use method reference for brevity:

serviceResponse.setProducts(serviceResponse.getProducts()
    .entrySet().stream()
    .filter(product -> productIds.stream().anyMatch(product.getKey()::startsWith))
    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)));

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=31387&siteId=1