通用的规则匹配算法(原创)(java+.net)

1.java里可以使用Spring的 Spel或者Google的Aviator

如果使用 Aviator 则添加以下依赖

      <dependency>
          <groupId>com.googlecode.aviator</groupId>
          <artifactId>aviator</artifactId>
          <version>4.1.2</version>
      </dependency>

 

不过,推荐使用Spel

 

一般的规则匹配最终都会采用如下表达式来计算

如   ( {status} in "2,3" && ({level} in "p1,p2" || {times} in "1,9"))

但是存储在DB中一般采用 List<Model>的方式来存储,这样方便管理界面的前端的渲染 (当然也不排除直接存储表达式的,不过前端的渲染就有些难度了)

 

整个解析过程实现过程有以下几步

1.存储的List中的规则转换为表达式 

   1.1 增加括号

   1.2 替换变量

   1.3 构造spel表达式

   1.4 连接下一个规则

2.计算表达式

 

代码如下:

import com.google.common.collect.ImmutableMap;


import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

 

 

@NoArgsConstructor
    @AllArgsConstructor
    @Data
    static class RuleItem {
        /**
         * 左变量
         */
        private String left;

        /**
         * 比较表达式
         */
        private ComparelOpration comparelOpration;

        /**
         * 右变量或者常量
         */
        private String right;

        /**
         * 连接下一个表达式的逻辑运算符
         */
        private LogicalOpration logicalOpra;
    }


    @NoArgsConstructor
    @AllArgsConstructor
    @Data
    static class RuleModel {
        /**
         * 规则列表
         */
        private List<RuleItem> ruleItems;

        /**
         * 左括号放在第几个Item之前
         */
        private List<Integer> leftParenthesesIndex;

        /**
         * 右括号放在第几个Item之后
         */
        private List<Integer> rightParenthesesIndex;
    }

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    static class SpelResult {
        private String express;
        private StandardEvaluationContext context;
    }

 

使用的两个连接器(比较连接和逻辑连接)

enum ComparelOpration {
        In,
        NotIn,
        GreaterThan,
        LessThan,
        GreaterEqualThan,
        LessEqualThan,
        Equal,
        NotEqual;

        public static boolean isDecimalCompareLogicalOpration(ComparelOpration opration) {
            return opration.ordinal() == ComparelOpration.GreaterThan.ordinal()
                    || opration.ordinal() == ComparelOpration.GreaterEqualThan.ordinal()
                    || opration.ordinal() == ComparelOpration.LessEqualThan.ordinal()
                    || opration.ordinal() == ComparelOpration.LessThan.ordinal();
        }

        public static boolean isEqualLogicalOpration(ComparelOpration opration) {
            return opration.ordinal() == ComparelOpration.Equal.ordinal()
                    || opration.ordinal() == ComparelOpration.NotEqual.ordinal()
                    ;
        }
    }

    enum LogicalOpration {
        None,
        And,
        Or;

        static String toStr(LogicalOpration logicalOpration) {
            return logicalOpration.ordinal() == LogicalOpration.None.ordinal()
                    ? ""
                    : (logicalOpration.ordinal() == LogicalOpration.And.ordinal() ? "&&" : "||");
        }
    }

 

匹配工厂如下

 static class SpelMatchFactory {
        private static final ExpressionParser parser = new SpelExpressionParser();

        static SpelResult toSpelExpress(RuleModel model, Map<String, String> userFeature) {
            List<RuleItem> ruleItemList = model.getRuleItems();
            StringBuilder sb = new StringBuilder();
            StandardEvaluationContext ctx = new StandardEvaluationContext();
            for (int i = 0; i < ruleItemList.size(); i++) {
                RuleItem item = ruleItemList.get(i);
                if (model.leftParenthesesIndex.contains(i)) {
                    sb.append("(");
                }

                String listKey = "list" + i;
                String valueKey = "item" + i;

                String subExpress = compute(item, listKey, valueKey);
                sb.append(subExpress);

                String leftValue = item.getLeft();
                if (leftValue.startsWith("{") && leftValue.endsWith("}")) {
                    leftValue = userFeature.get(leftValue.substring(1, leftValue.length() - 1));
                }

                String rightValue = item.getRight();
                if (rightValue.startsWith("{") && rightValue.endsWith("}")) {
                    rightValue = userFeature.get(rightValue.substring(1, rightValue.length() - 1));
                }
// 这里暂时只支持 Integer和String 两种变量类型
                if (ComparelOpration.isDecimalCompareLogicalOpration(item.comparelOpration)) {
                    ctx.setVariable(listKey, Integer.parseInt(rightValue));
                    ctx.setVariable(valueKey, Integer.parseInt(leftValue));
                } else if (ComparelOpration.isEqualLogicalOpration(item.comparelOpration)) {
                    ctx.setVariable(listKey, rightValue);
                    ctx.setVariable(valueKey, leftValue);
                } else {
                    ctx.setVariable(listKey, Arrays.asList(rightValue.split(",")));
                    ctx.setVariable(valueKey, leftValue);
                }

                if (model.rightParenthesesIndex.contains(i)) {
                    sb.append(")");
                }

                if (item.logicalOpra.ordinal() != LogicalOpration.None.ordinal()) {
                    sb.append(LogicalOpration.toStr(item.getLogicalOpra()));
                }
            }

            return new SpelResult(sb.toString(), ctx);
        }

        public static boolean compute(RuleModel model, Map<String, String> userFeature) {
            SpelResult spelExpressResult = SpelMatchFactory.toSpelExpress(model, userFeature);

            Boolean execResult = parser.parseExpression(spelExpressResult.getExpress()).getValue(
                    spelExpressResult.getContext(),
                    Boolean.class);
            return execResult;
        }

        private static String compute(RuleItem matchItem, String listKey, String valueKey) {
            if (matchItem.getComparelOpration().ordinal() == ComparelOpration.Equal.ordinal()) {
                return "#" + listKey + ".equals(#" + valueKey + ")";
            }

            if (matchItem.getComparelOpration().ordinal() == ComparelOpration.NotEqual.ordinal()) {
                return "!#" + listKey + ".equals(#" + valueKey + ")";
            }

            if (matchItem.getComparelOpration().ordinal() == ComparelOpration.In.ordinal()) {
                return "#" + listKey + ".contains(#" + valueKey + ")";
            }
            if (matchItem.getComparelOpration().ordinal() == ComparelOpration.NotIn.ordinal()) {
                return "!#" + listKey + ".contains(#" + valueKey + ")";
            }
            if (matchItem.getComparelOpration().ordinal() == ComparelOpration.GreaterEqualThan.ordinal()) {
                return "#" + valueKey + ">=" + "#" + listKey;
            }

            if (matchItem.getComparelOpration().ordinal() == ComparelOpration.LessEqualThan.ordinal()) {
                return "#" + valueKey + "<=" + "#" + listKey;
            }

            if (matchItem.getComparelOpration().ordinal() == ComparelOpration.GreaterThan.ordinal()) {
                return "#" + valueKey + ">" + "#" + listKey;
            }

            if (matchItem.getComparelOpration().ordinal() == ComparelOpration.LessThan.ordinal()) {
                return "#" + valueKey + "<" + "#" + listKey;
            }

            throw new IllegalArgumentException("不支持的逻辑运算类型");
        }
    }

 

 

最后 ,测试代码如下:

public static void main(String[] args) {
        List<RuleItem> ruleItems = new ArrayList<>();
        ruleItems.add(new RuleItem("{status}", ComparelOpration.In, "2,3", LogicalOpration.Or));
        ruleItems.add(new RuleItem("{level}", ComparelOpration.In, "1,2", LogicalOpration.And));
        ruleItems.add(new RuleItem("{hours}", ComparelOpration.GreaterEqualThan, "48", LogicalOpration.And));
        ruleItems.add(new RuleItem("{phone1}", ComparelOpration.Equal, "{phone2}", LogicalOpration.None));
        RuleModel model = new RuleModel();
        model.setRuleItems(ruleItems);

        //左括号在0的位置之前
        model.setLeftParenthesesIndex(Arrays.asList(0));
        //右括号在1的位置之后
        model.setRightParenthesesIndex(Arrays.asList(1));
       //以上表达式相当于 ({status} in '2,3' or {level} in '1,2') && {hours}>=48 && {phone1}=={phone2}

        //1. {phone1} != {phone2} ,结果为false
        Map<String, String> userFeature1 = ImmutableMap.of("status", "2", "level", "1", "phone1",
                "13900000000", "phone2", "13900000001", "hours", "66");
        boolean computeResult = SpelMatchFactory.compute(model, userFeature1);
        System.out.println("userFeature1的匹配结果:" + computeResult);


        //2.{hours} < 48 ,结果为false
        Map<String, String> userFeature2 = ImmutableMap.of("status", "2", "level", "1", "phone1",
                "13900000000", "phone2", "13900000001", "hours", "6");
        computeResult = SpelMatchFactory.compute(model, userFeature2);
        System.out.println("userFeature2的匹配结果:" + computeResult);


        //3. {status} 不在 2,3 中,但是 level 在 1,2中,结果为true
        Map<String, String> userFeature3 = ImmutableMap.of("status", "1", "level", "1", "phone1",
                "13900000000", "phone2", "13900000000", "hours", "66");
        computeResult = SpelMatchFactory.compute(model, userFeature3);
        System.out.println("userFeature3的匹配结果:" + computeResult);

        //4. {status} 不在 2,3 中,且 level 不在 1,2中,结果为false
        Map<String, String> userFeature4 = ImmutableMap.of("status", "1", "level", "3", "phone1",
                "13900000000", "phone2", "13900000000", "hours", "66");
        computeResult = SpelMatchFactory.compute(model, userFeature4);
        System.out.println("userFeature4的匹配结果:" + computeResult);

        //4.一切都匹配,返回true
        Map<String, String> userFeature5 = ImmutableMap.of("status", "2", "level", "1", "phone1",
                "13900000000", "phone2", "13900000000", "hours", "66");
        computeResult = SpelMatchFactory.compute(model, userFeature5);
        System.out.println("userFeature5的匹配结果:" + computeResult);
    }

 

输出结果为:

表达式:(#list0.contains(#item0)||#list1.contains(#item1))&&#item2>=#list2&&#list3.equals(#item3)
userFeature1的匹配结果:false
表达式:(#list0.contains(#item0)||#list1.contains(#item1))&&#item2>=#list2&&#list3.equals(#item3)
userFeature2的匹配结果:false
表达式:(#list0.contains(#item0)||#list1.contains(#item1))&&#item2>=#list2&&#list3.equals(#item3)
userFeature3的匹配结果:true
表达式:(#list0.contains(#item0)||#list1.contains(#item1))&&#item2>=#list2&&#list3.equals(#item3)
userFeature4的匹配结果:false
表达式:(#list0.contains(#item0)||#list1.contains(#item1))&&#item2>=#list2&&#list3.equals(#item3)
userFeature5的匹配结果:true

 

 

 

完整代码如下

import com.google.common.collect.ImmutableMap;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.util.Assert;

import java.math.BigDecimal;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

public class SpelMatchFactory {
    private static final ExpressionParser parser = new SpelExpressionParser();

    static SpelResult toSpelExpress(RuleModel model, Map<String, String> userFeature) {
        List<RuleItem> ruleItemList = model.getRuleItems();
        StringBuilder sb = new StringBuilder();
        StandardEvaluationContext ctx = new StandardEvaluationContext();
        for (int i = 0; i < ruleItemList.size(); i++) {
            RuleItem item = ruleItemList.get(i);
            if (model.leftParenthesesIndex.contains(i)) {
                sb.append("(");
            }

            String listKey = "list" + i;
            String valueKey = "item" + i;

            String subExpress = compute(item, listKey, valueKey);
            sb.append(subExpress);

            String leftValue = item.getLeft();
            if (leftValue.startsWith("{") && leftValue.endsWith("}")) {
                leftValue = userFeature.get(leftValue.substring(1, leftValue.length() - 1));
            }

            String rightValue = item.getRight();
            if (rightValue.startsWith("{") && rightValue.endsWith("}")) {
                rightValue = userFeature.get(rightValue.substring(1, rightValue.length() - 1));
            }

            if (ComparelOpration.isDecimalCompareLogicalOpration(item.comparelOpration)) {
                ctx.setVariable(listKey, new BigDecimal(rightValue));
                ctx.setVariable(valueKey, new BigDecimal(leftValue));
            } else if (ComparelOpration.isEqualLogicalOpration(item.comparelOpration)) {
                ctx.setVariable(listKey, rightValue);
                ctx.setVariable(valueKey, leftValue);
            } else {
                if (rightValue.startsWith("'") && rightValue.endsWith("'")) {
                    rightValue = rightValue.substring(1, rightValue.length() - 1);
                }
                if (rightValue.startsWith("\"") && rightValue.endsWith("\"")) {
                    rightValue = rightValue.substring(1, rightValue.length() - 1);
                }
                ctx.setVariable(listKey, Arrays.asList(rightValue.split(",")));
                ctx.setVariable(valueKey, leftValue);
            }

            if (model.rightParenthesesIndex.contains(i)) {
                sb.append(")");
            }

            if (item.logicalOpra.ordinal() != LogicalOpration.None.ordinal()) {
                sb.append(LogicalOpration.toStr(item.getLogicalOpra()));
            }
        }

        return new SpelResult(sb.toString(), ctx);
    }

    public static boolean compute(String expression, Map<String, String> userFeature) {
        RuleModel model = toRuleModel(expression);

        return compute(model, userFeature);
    }

    public static boolean compute(RuleModel model, Map<String, String> userFeature) {
        SpelResult spelExpressResult = SpelMatchFactory.toSpelExpress(model, userFeature);

        Boolean execResult = parser
                .parseExpression(spelExpressResult.getExpress())
                .getValue(spelExpressResult.getContext(), Boolean.class);
        return execResult;
    }

    private static String compute(RuleItem matchItem, String listKey, String valueKey) {
        if (matchItem.getComparelOpration().ordinal() == ComparelOpration.Equal.ordinal()) {
            return "#" + listKey + ".equals(#" + valueKey + ")";
        }

        if (matchItem.getComparelOpration().ordinal() == ComparelOpration.NotEqual.ordinal()) {
            return "!#" + listKey + ".equals(#" + valueKey + ")";
        }

        if (matchItem.getComparelOpration().ordinal() == ComparelOpration.In.ordinal()) {
            return "#" + listKey + ".contains(#" + valueKey + ")";
        }
        if (matchItem.getComparelOpration().ordinal() == ComparelOpration.NotIn.ordinal()) {
            return "!#" + listKey + ".contains(#" + valueKey + ")";
        }
        if (matchItem.getComparelOpration().ordinal() == ComparelOpration.GreaterEqualThan.ordinal()) {
            return "#" + valueKey + ">=" + "#" + listKey;
        }

        if (matchItem.getComparelOpration().ordinal() == ComparelOpration.LessEqualThan.ordinal()) {
            return "#" + valueKey + "<=" + "#" + listKey;
        }

        if (matchItem.getComparelOpration().ordinal() == ComparelOpration.GreaterThan.ordinal()) {
            return "#" + valueKey + ">" + "#" + listKey;
        }

        if (matchItem.getComparelOpration().ordinal() == ComparelOpration.LessThan.ordinal()) {
            return "#" + valueKey + "<" + "#" + listKey;
        }

        throw new IllegalArgumentException("不支持的逻辑运算类型");
    }

    @NoArgsConstructor
    @AllArgsConstructor
    @Data
    static class RuleItem {
        /**
         * 左变量
         */
        private String left;

        /**
         * 比较表达式
         */
        private ComparelOpration comparelOpration;

        /**
         * 右变量或者常量
         */
        private String right;

        /**
         * 连接下一个表达式的逻辑运算符
         */
        private LogicalOpration logicalOpra = LogicalOpration.None;

        @Override
        public String toString() {
            return String.join(" ", left, comparelOpration.getCode(), right);
        }
    }


    @NoArgsConstructor
    @AllArgsConstructor
    @Data
    static class RuleModel {
        /**
         * 规则列表
         */
        private List<RuleItem> ruleItems;

        /**
         * 左括号放在第几个Item之前
         */
        private List<Integer> leftParenthesesIndex;

        /**
         * 右括号放在第几个Item之后
         */
        private List<Integer> rightParenthesesIndex;

        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < ruleItems.size(); i++) {
                if (leftParenthesesIndex.contains(i)) {
                    sb.append("(");
                }
                sb.append(ruleItems.get(i).toString());

                if (rightParenthesesIndex.contains(i)) {
                    sb.append(")");
                }
                if (!ruleItems.get(i).getLogicalOpra().equals(LogicalOpration.None)) {
                    sb.append(" ").append(ruleItems.get(i).getLogicalOpra().getCode()).append(" ");
                }
            }
            return sb.toString();
        }
    }


    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    @Builder
    static class SpelResult {
        private String express;
        private StandardEvaluationContext context;
    }

    private static RuleModel toRuleModel(String expression) {
        // ({status} in '2,3' or {level} in '1,2') && {hours}>=48 && {phone1}=={phone2}
        // 1. 从头开始查找 ,直到找到 and/or为止
        List<String> ruleExpressions = Arrays.asList(expression.split(" "));
        int i = -1;
        int startIdx = 0;
        List<RuleItem> collect = new ArrayList<>();
        List<Integer> leftParenthesesIndex = new ArrayList<>();
        List<Integer> rightParenthesesIndex = new ArrayList<>();
        while (++i < ruleExpressions.size()) {
            if (ruleExpressions.get(i).equals("and") || ruleExpressions.get(i).equals("or")) {
                String logicalOperation = ruleExpressions.get(i);
                // 将之前的所有
                String ruleExpression = String.join(" ", ruleExpressions.subList(startIdx, i)).trim();
                if (ruleExpression.startsWith("(")) {
                    leftParenthesesIndex.add(collect.size());
                    ruleExpression = ruleExpression.substring(1);
                }
                if (ruleExpression.endsWith(")")) {
                    rightParenthesesIndex.add(collect.size());
                    ruleExpression = ruleExpression.substring(0, ruleExpression.length() - 1);
                }
                RuleItem ruleItem = toRuleItem(ruleExpression);
                startIdx = i + 1;
                collect.add(ruleItem);
                if (logicalOperation.equals("and")) {
                    ruleItem.logicalOpra = LogicalOpration.And;
                } else {
                    ruleItem.logicalOpra = LogicalOpration.Or;
                }
            }
        }


        if (startIdx < ruleExpressions.size()) {
            String ruleExpression = String.join(" ", ruleExpressions.subList(startIdx, ruleExpressions.size())).trim();
            if (ruleExpression.startsWith("(")) {
                leftParenthesesIndex.add(collect.size());
                ruleExpression = ruleExpression.substring(1);
            }
            if (ruleExpression.endsWith(")")) {
                rightParenthesesIndex.add(collect.size());
                ruleExpression = ruleExpression.substring(0, ruleExpression.length() - 1);
            }
            RuleItem ruleItem = toRuleItem(ruleExpression);
            collect.add(ruleItem);
        }

        RuleModel model = new RuleModel();
        model.setRuleItems(collect);
        model.setLeftParenthesesIndex(leftParenthesesIndex);
        model.setRightParenthesesIndex(rightParenthesesIndex);
        Assert.isTrue(leftParenthesesIndex.size() == rightParenthesesIndex.size(), "括号不能封闭");
        return model;
    }

    private static RuleItem toRuleItem(String expression) {
        // {status} in '2,3'
        RuleItem result = new RuleItem();
        List<String> ruleExpressions = Arrays.asList(expression.split(" "));
        Assert.isTrue(ruleExpressions.size() == 3, "");
        int i = 1;
        if (ruleExpressions.get(i).equals("in")
                || ruleExpressions.get(i).equals("==")
                || ruleExpressions.get(i).equals("!=")
                || ruleExpressions.get(i).equals(">=")
                || ruleExpressions.get(i).equals("<=")
                || ruleExpressions.get(i).equals(">")
                || ruleExpressions.get(i).equals("<")
        ) {
            String comparelOpration = ruleExpressions.get(i);
            // 将之前的所有
            result.left = ruleExpressions.get(0);
            result.right = ruleExpressions.get(2);
            if (comparelOpration.equals("==")) {
                result.comparelOpration = ComparelOpration.Equal;
            } else if (comparelOpration.equals("!=")) {
                result.comparelOpration = ComparelOpration.NotEqual;
            } else if (comparelOpration.equals("in")) {
                result.comparelOpration = ComparelOpration.In;
            } else if (comparelOpration.equals("notIn")) {
                result.comparelOpration = ComparelOpration.NotIn;
            } else if (comparelOpration.equals(">=")) {
                result.comparelOpration = ComparelOpration.GreaterEqualThan;
            } else if (comparelOpration.equals("<=")) {
                result.comparelOpration = ComparelOpration.LessEqualThan;
            } else if (comparelOpration.equals(">")) {
                result.comparelOpration = ComparelOpration.GreaterThan;
            } else if (comparelOpration.equals("<")) {
                result.comparelOpration = ComparelOpration.LessThan;
            }
        }

        return result;
    }
public enum ComparelOpration {
    In("in"),
    NotIn("notIn"),
    GreaterThan(">"),
    LessThan("<"),
    GreaterEqualThan(">="),
    LessEqualThan("<="),
    Equal("=="),
    NotEqual("!=");
    private String code;

    ComparelOpration(String code) {
        this.code = code;
    }

    public static boolean isDecimalCompareLogicalOpration(ComparelOpration opration) {
        return opration.ordinal() == ComparelOpration.GreaterThan.ordinal()
                || opration.ordinal() == ComparelOpration.GreaterEqualThan.ordinal()
                || opration.ordinal() == ComparelOpration.LessEqualThan.ordinal()
                || opration.ordinal() == ComparelOpration.LessThan.ordinal();
    }

    public static boolean isEqualLogicalOpration(ComparelOpration opration) {
        return opration.ordinal() == ComparelOpration.Equal.ordinal()
                || opration.ordinal() == ComparelOpration.NotEqual.ordinal()
                ;
    }

    public String getCode(){
        return this.code;
    }
}
public enum LogicalOpration {
    None(""),
    And("and"),
    Or("or");
    private String code;

    LogicalOpration(String code) {
        this.code = code;
    }

    static String toStr(LogicalOpration logicalOpration) {
        return logicalOpration.ordinal() == LogicalOpration.None.ordinal()
                ? ""
                : (logicalOpration.ordinal() == LogicalOpration.And.ordinal() ? "&&" : "||");
    }

    public String getCode() {
        return code;
    }
}
public static void main(String[] args) {
        String expression = "({status} in '2,3' or {level} in '1,2') and ({hours} >= 48) and ({phone1} == {phone2})";
        RuleModel model = toRuleModel(expression);
        System.out.println(model.toString());
        /*List<RuleItem> ruleItems = new ArrayList<>();
        ruleItems.add(new RuleItem("{status}", ComparelOpration.In, "2,3", LogicalOpration.Or));
        ruleItems.add(new RuleItem("{level}", ComparelOpration.In, "1,2", LogicalOpration.And));
        ruleItems.add(new RuleItem("{hours}", ComparelOpration.GreaterEqualThan, "48", LogicalOpration.And));
        ruleItems.add(new RuleItem("{phone1}", ComparelOpration.Equal, "{phone2}", LogicalOpration.None));
        RuleModel model = new RuleModel();
        model.setRuleItems(ruleItems);

        //左括号在0的位置之前
        model.setLeftParenthesesIndex(Collections.singletonList(0));
        //右括号在1的位置之后
        model.setRightParenthesesIndex(Collections.singletonList(1));
        //以上表达式相当于 ({status} in '2,3' or {level} in '1,2') && {hours}>=48 && {phone1}=={phone2}
*/
        //1. {phone1} != {phone2} ,结果为false
        Map<String, String> userFeature1 = ImmutableMap.of("status", "2", "level", "1", "phone1",
                "13900000000", "phone2", "13900000001", "hours", "66");
        boolean computeResult = SpelMatchFactory.compute(model, userFeature1);
        System.out.println("userFeature1的匹配结果:" + computeResult);


        //2.{hours} < 48 ,结果为false
        Map<String, String> userFeature2 = ImmutableMap.of("status", "2", "level", "1", "phone1",
                "13900000000", "phone2", "13900000001", "hours", "6");
        computeResult = SpelMatchFactory.compute(model, userFeature2);
        System.out.println("userFeature2的匹配结果:" + computeResult);


        //3. {status} 不在 2,3 中,但是 level 在 1,2中,结果为true
        Map<String, String> userFeature3 = ImmutableMap.of("status", "1", "level", "1", "phone1",
                "13900000000", "phone2", "13900000000", "hours", "66");
        computeResult = SpelMatchFactory.compute(model, userFeature3);
        System.out.println("userFeature3的匹配结果:" + computeResult);

        //4. {status} 不在 2,3 中,且 level 不在 1,2中,结果为false
        Map<String, String> userFeature4 = ImmutableMap.of("status", "1", "level", "3", "phone1",
                "13900000000", "phone2", "13900000000", "hours", "66");
        computeResult = SpelMatchFactory.compute(model, userFeature4);
        System.out.println("userFeature4的匹配结果:" + computeResult);

        //4.一切都匹配,返回true
        Map<String, String> userFeature5 = ImmutableMap.of("status", "2", "level", "1", "phone1",
                "13900000000", "phone2", "13900000000", "hours", "66");
        computeResult = SpelMatchFactory.compute(model, userFeature5);
        System.out.println("userFeature5的匹配结果:" + computeResult);
    }

 

posted @ 2019-07-26 13:36  zslm___  阅读(1636)  评论(0编辑  收藏  举报