如何让匹配算法保持高效优雅

脱离了实际业务场景的架构设计和算法将是没有价值,或称为“耍流氓”。

本章将根据实际业务案例(请允许我将业务模糊一下)讲解 “匹配算法” 的设计和实现;

业务:在众多的数据行项目下,通过数据源匹配目标源,找到最优匹配项
分析:数据源作为标准,并定义匹配的元素以及优先级,目标源中可能匹配到多个,但是需要找到最优的并且占用掉;简单点讲,就像根据自己的标准找对象一样,最多一个。

实现:数据源sourceItems,目标源 targetItems,匹配因素 tokens,优先级:order

咱们根据实现一步一步讲解:

先定义注解,用于对匹配因素的解释,



@Target({
   ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface SmartMatch {
   

}

@Target({
   ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@SmartMatch
public @interface SmartMatchCol {
   

    String value() default "";

    /**
     * alias
     * @return
     */
    String name();

    /**
     * 序列
     * @return
     */
    int index() default 0;

    /**
     * 优先级
     * @return
     */
    int order() default 0;

}

注释的类统一解释放入容器中 ,



public class FieldToken implements Serializable, Cloneable {
   

    private final String field;
    private final String name;
    private transient final SmartMatchCol smartMatchCol;
    private final int order;
    private boolean match;

    public FieldToken(String field, SmartMatchCol smartMatchCol) {
   
        this.field = field;
        this.smartMatchCol = smartMatchCol;
        this.name = smartMatchCol.name();
        this.order = smartMatchCol.order();
        this.match = false;
    }

    public String getField() {
   
        return field;
    }

    public SmartMatchCol getSmartMatchCol() {
   
        return smartMatchCol;
    }

    public String getName() {
   
        return name;
    }

    public int getOrder() {
   
        return order;
    }

    public boolean isMatch() {
   
        return match;
    }

    public void setMatch(boolean match) {
   
        this.match = match;
    }

    @Override
    public FieldToken clone() throws CloneNotSupportedException {
   
        return (FieldToken) super.clone();
    }

}

对以上注解的类进行统一处理,



@Slf4j
@Component
public class SmartMatchSelector {
   
	/**
	* 需要扫描的包
	*/
    private final String rootPackage = "com.xx";
    private final Map<Class<?>, List<FieldToken>> fieldMaps = new ConcurrentHashMap<>();
    private final Object locker = new Object();

    @PostConstruct
    private void init() {
   
        try {
   
            findMatchingClasses().forEach(a -> fieldMaps.put(a, findMatchingFields(a)));
        } catch (ClassNotFoundException e) {
   
            e.printStackTrace();
        }

    }


    private <T> List<FieldToken> getFieldToken(Class<T> clazz) {
   
        if (!fieldMaps.containsKey(clazz)) {
   
            synchronized (locker) {
   
                if (!fieldMaps.containsKey(clazz)) {
   
                    fieldMaps.put(clazz, findMatchingFields
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值