使用@FunctionalInterface抽离冗余代码

       现在前端使用elementui中的tree组件,需要后端返回树结构的数据,但是数据库中存储的扁平化的数据,例如id,parentId。需要进行写个工具栏去进行统一处理。

       首先引入了一个名为 buildTree 的通用方法,使用一个函数式接口 NodeMapper<T> 来映射不同类型的实体到 TreeVo 对象。

      这使得在创建树形结构时只需编写一次通用逻辑,而不需要重复实现相似的代码。 映射逻辑: 在 buildTree 方法中,我们针对不同的实体类型使用一个 Lambda 表达式来指定如何从实体构建 TreeVo 对象。这为各种树结构的构建提供了灵活性。 提高了代码的可读性与可维护性。以后若有新的树形结构只需要简单地调用 buildTree 方法,并提供合适的映射逻辑即可。下面先给出工具类示例。

​

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

public class TreeVoUtils {

    public static List<TreeVo> buildEquipmentTypeTree(List<EquipmentType> dataList) {
        return buildTree(dataList, (item) -> new TreeVo() {{
            setId(item.getId());
            setParentId(item.getParentId());
            setName(item.getName());
            setNumber(item.getNumber());
            setStatus(item.getStatus());
            setRemark(item.getRemark());
        }});
    }

    public static List<TreeVo> buildEquipmentKeyComponentsTree(List<EquipmentKeyComponents> dataList) {
        return buildTree(dataList, (item) -> new TreeVo() {{
            setId(item.getId());
            setParentId(item.getParentId());
            setName(item.getName());
            setNumber(item.getNumber());
            setChangeFrequency(item.getChangeFrequency());
            setIsKey(item.getIsKey());
            setRemark(item.getRemark());
        }});
    }

    public static List<TreeVo> buildDocumentFolderTree(List<DocumentFolder> dataList) {
        return buildTree(dataList, (item) -> new TreeVo() {{
            setId(item.getId());
            setParentId(item.getParentId());
            setName(item.getName());
            setRemark(item.getRemark());
        }});
    }

    public static List<TreeVo> buildMaterialCategoryTree(List<MaterialCategory> dataList) {
        return buildTree(dataList, (item) -> new TreeVo() {{
            setId(item.getId());
            setParentId(item.getParentId());
            setName(item.getName());
            setRemark(item.getRemark());
        }});
    }

    private static <T> List<TreeVo> buildTree(List<T> dataList, NodeMapper<T> mapper) {
        Map<Long, TreeVo> nodeMap = new HashMap<>();
        List<TreeVo> roots = new ArrayList<>();

        for (T item : dataList) {
            TreeVo node = mapper.map(item);
            nodeMap.put(node.getId(), node);

            Long parentId = node.getParentId();
            if (parentId == null) {
                roots.add(node);
            } else {
                TreeVo parent = nodeMap.get(parentId);
                if (parent != null) {
                    if (parent.getChildren() == null) {
                        parent.setChildren(new ArrayList<>());
                    }
                    parent.getChildren().add(node);
                }
            }
        }
        return roots;
    }

    @FunctionalInterface
    private interface NodeMapper<T> {
        TreeVo map(T item);
    }
}

​

@FunctionalInterface 注解和定义的 NodeMapper<T> 接口在上述代码中扮演了一个重要的角色,

@FunctionalInterface 注解 定义 @FunctionalInterface 是一个用于标记接口的注解,表示这个接口是一个函数式接口(Functional Interface)。 特性 函数式接口是只包含一个抽象方法的接口。这样的接口可以被隐式地转换为 Lambda 表达式或方法引用。 在编译时,如果接口中包含多个抽象方法,编译器会抛出错误,确保符合函数式接口的定义。

        NodeMapper<T> 接口 定义 NodeMapper<T> 是一个泛型接口,定义了一个方法 map(T item),它接受一个类型为 T 的参数,并返回一个 TreeVo 类型的对象。 目的 这个接口的主要目的是为构建树形结构提供一种灵活的映射机制。它允许传入不同类型的实体对象(如 EquipmentType, EquipmentKeyComponents, DocumentFolder, MaterialCategory 等),并通过实现 map 方法来指定如何把这些实体对象转化为 TreeVo 对象。 

        这样,即使以后需要对映射逻辑进行更改或对其他类型进行映射,只需传入不同的 Lambda 表达式即可,保证了代码的灵活性和可扩展性。 总结 NodeMapper<T> 接口的定义及其作为函数式接口的使用,使得在构建树形结构时,可以灵活地处理多种不同类型的输入,提供了一种干净的方式来映射数据,减少了重复代码,同时增强了代码的可读性和维护性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值