如何使用多个参数过滤流数据?

斯里兰卡

我有一个来自S3中存储的JSON文件的来源列表。我需要在列表的几个字段上提供搜索过滤器。我创建了一个Builder类,其中包含所有需要过滤数据的字段。

现在,我想使用Java流,并根据用户将提供的参数将过滤器应用于数据。用户可以根据需要提供全部6个参数,或者仅传递2个或3个参数。例如,用户仅提供6个参数中的2个,我应该能够基于给定的2个参数过滤数据,而忽略值为空的4个参数。

public class ListOfFields {
    private String country;
    @JsonProperty("product")
    private String product;
    private String transactionId;
    private String sourceBy;
    private String category;
    private String specialTag;
    private String organicTag;
    private String successTag;
    private String speedTag;
    private String foodTag;
    private String costPrice;
    private String fruitType;
    private String fruitVendorId;    
} 

下面是builder类

public class ProductClass {
    @Builder.Default
    private String country = 'UnitedStates';
    private String sourceBy;
    private Boolean specialTag;
    private String category;
    private Boolean priceTag;
    private String fruitType;
}  

用户可以通过以下方法致电获取产品

public String getProduct(ProductClass productQuery) {      
    List<ListOfFields> result = listOfFields // (the declaration is made before in the class as private List<ListOfFields> listOfFields;)
            .stream().filter(productQuery::match)
            .collect(Collectors.toList());

我如何提出动态谓词作为上述匹配功能?我应该能够对用户提供的参数进行过滤,无论是1还是2或3或4 ...,并且不使用用户未在过滤条件中传递任何值的参数。

纳曼:

考虑到ProductClass作为输入和null用于不存在的键的值。您可以Predicate使用包含实际查询参数的方法来定义可能的列表

private static List<Predicate<ListOfFields>> predicates(ProductClass product) {
    return List.of(
            lof -> product.priceTag != null && product.priceTag,
            lof -> product.specialTag != null && product.specialTag,
            lof -> product.country != null && product.country.equals(lof.country),
            lof -> product.sourceBy != null && product.sourceBy.equals(lof.sourceBy),
            lof -> product.category != null && product.category.equals(lof.category),
            lof -> product.fruitType != null && product.fruitType.equals(lof.fruitType)
    );
}

达到此目标后,列表可以被reduced表示为单个,Predicate例如:

private static Predicate<ListOfFields> matchAll(List<Predicate<ListOfFields>> queries) {
    return queries.stream()
            .reduce(Predicate::and)
            .orElse(p -> true);
}

现在,人们可以很容易地在使用stream类型谓词时使用此谓词ListOfFields-

List<ListOfFields> result = listOfFields.stream()
        .filter(matchAll(predicates(productQuery)))
        .collect(Collectors.toList());

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章