简体   繁体   English

如何迭代谓词列表

[英]How to iterate a list of Predicates

I have a spring boot application and we have an application.yml with a set of feature flags on it我有一个 spring boot 应用程序,我们有一个带有一组功能标志的 application.yml

featureFlag:
    featureOne:true
    featureTwo:true
    featureThree:true
    featureFour:false

Then this file is read by a this class然后这个文件被一个这个类读取

@Configuration
@ConfigurationProperties(prefix="featureFlag")
public class FeatureFlag{

private Boolean featureOne;
private Boolean featureTwo;
private Boolean featureThree;
private Boolean featureFour;
/*The predicates based on the feature flags*/

private Predicate<FeatureFlag> isFeatureFlagOneEnabled = featureFlag.isFeatureOne();
private Predicate<FeatureFlag> isFeatureFlagTwoEnabled = featureFlag.isFeatureTwo();
private Predicate<FeatureFlag> isFeatureFlagThreeEnabled = featureFlag.isFeatureThree();
private Predicate<FeatureFlag> isFeatureFlagFourEnabled = featureFlag.isFeatureFour();
}

I want to pass the actual predicate and iterate each one of them but I want to know if I can do a generic function that I pass the list of Predicates with its value to be tested and if all of them are true the function return me a true otherwise false我想传递实际的谓词并迭代它们中的每一个,但我想知道我是否可以做一个通用函数,我将传递带有要测试的值的谓词列表,如果所有这些都为真,则该函数返回给我一个真否则假

Then in this class add some code like this because I want to generate this list on demand, for example I have a client x that purchase featureOne and featureTwo, in this example I create a list like this然后在这个类中添加一些这样的代码,因为我想按需生成这个列表,例如我有一个客户 x 购买了 featureOne 和 featureTwo,在这个例子中我创建了一个这样的列表

Set<Predicate<FeatureFlag>> rulesForClientX = new HashSet<>();
rulesForClientX.add(isFeatureFlagOneEnabled);
rulesForClientX.add(isFeatureFlagTwoEnabled);

Then I want to create a specific logic for that client and pass it the list of predicates previously created, but I think I would need something like this然后我想为该客户端创建一个特定的逻辑并将之前创建的谓词列表传递给它,但我想我需要这样的东西

Function<List<Predicate<FeatureFlag>>, Boolean> iteratePredicates = (predicates) -> { 
    //test each predicate and return true if all of them are true otherwise return false
}

You can create a method that accepts Set<Predicate<FeatureFlag>> and value, then you can stream set of predicates and use allMatch您可以创建一个接受Set<Predicate<FeatureFlag>>和值的方法,然后您可以流式传输谓词集并使用allMatch

public boolean testPredicates(Set<Predicate<FeatureFlag>> predicates, Integer value) {
  return predicates.stream().allMatch(pre->pre.test(value));

 }

Chain Predicate sPredicate

What you should look forward to is chaining the predicates that you have.您应该期待的是链接您拥有的谓词。

I pass the list of Predicates with its value to be tested and if all of them are true the function return me a true otherwise false我传递了 Predicates 列表及其要测试的值,如果它们都为真,则函数返回真,否则为假

Based on your requirements this should look like;根据您的要求,这应该是这样的;

public Predicate<FeatureFlag> chainPredicates(Set<Predicate<FeatureFlag>> predicates) {
    return predicates.stream()
                     .reduce(Predicate::and) // all true
                     .orElse(p -> false); // or false
}

Consume Predicate消费Predicate

Further now, you can consume this single Predicate easily as现在,您可以轻松地使用这个单一的Predicate作为

boolean testFeatureFlag(Set<Predicate<FeatureFlag>> predicates, FeatureFlag value) {
    return chainPredicates(predicates).test(value);
}

or on a collection say a List<FeatureFlag> to filter out specific FeatureFlag s as:或者在集合上说一个List<FeatureFlag>来过滤掉特定的FeatureFlag s:

List<FeatureFlag> selectiveFeatures(Set<Predicate<FeatureFlag>> predicates, List<FeatureFlag> featureFlags) {
    Predicate<FeatureFlag> flagPredicate  = chainPredicates(predicates);
    return featureFlags.stream()
            .filter(flagPredicate)
            .collect(Collectors.toList());
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM