如何重构非标准结构的树形结构数据

如何重构非标准结构的树形结构数据

大家好!不知你在java编程过程中,是否遇到过非标准数据结构的数据对象,需要进行数据重组成java中的树形对象,再返给前端?

昨日

为了尽快让前端拿到测试数据,应付着先写了个性能很差劲的,调用了大量的mybatis查询,导致性能很慢:
1.先说数据结构:
工厂-车间-线体
工厂具有工厂名称,代码,车间集合三个属性;
车间具有车间名称,代码,线体集合三个属性;
2. 然而数据库中往往只能查询到,工厂名称、工厂代码、车间名称、车间代码、线体名称、线体代码这类似的平铺数据集合。
3. 如何将数据组装好返回给前端展示呢?
4. 简单粗暴的就是遍历,先查返回的工厂,然后再把工厂带进查询车间的查询条件中,再把工厂和车间带到查询线体的条件中。
5. 比如这样??

List<AppSaleReqConditionDto> queryFactoryInfo(@Param("scheduleNo") String scheduleNo, @Param("symbol") String symbol,@Param("scheduleDate") String scheduleDate);
List<AppSaleReqConditionDto.AppTreeWorkshop> queryWorkShopInfo(@Param("factoryCode") String factoryCode,@Param("scheduleNo") String scheduleNo, @Param("symbol") String symbol,@Param("scheduleDate") String scheduleDate);
List<AppSaleReqConditionDto.AppTreeLines> queryLineInfo(@Param("factoryCode") String factoryCode,@Param("workshopCode") String workshopCode,@Param("scheduleNo") String scheduleNo, @Param("symbol") String symbol,@Param("scheduleDate") String scheduleDate);
  1. 然而这样会再次通过数据库查询多次数据库,性能影响太大。

代码优化

1.今天,抽出空余时间,想对这个问题进行优化一下。如何优化?查询平铺数据后,用程序组装数据结构,但是数据结构不是简单的父子节点,相同的数据结构。
2.那就不用递归,直接遍历。
3.核心代码:

/**
     * 重构平铺数据为树形结构
     *
     * @param list
     * @param result
     * @return
     */
    public List<AppSaleReqConditionDto> refactorData(List<AppFactoryWorkShopLineDto> list, List<AppSaleReqConditionDto> result) {
        for (int i = 0; i < list.size(); i++) {
            AppFactoryWorkShopLineDto item = list.get(i);
            boolean containsFactory = AppSaleReqConditionDto.isContainsFactory(result, item);
            if (!containsFactory) {
                result.add(new AppSaleReqConditionDto(item.getFactoryName(), item.getFactoryCode()));
            }
            boolean containsWorkShop = AppSaleReqConditionDto.isContainsWorkShop(result, item);
            if (!containsWorkShop) {
                for (int j = 0; j < result.size(); j++) {
                    AppSaleReqConditionDto itemFactory = result.get(j);
                    if (itemFactory.getFactoryCode().equals(item.getFactoryCode()) && itemFactory.getFactoryName().equals(item.getFactoryName())) {
                        itemFactory.getWorkshops().add(new AppSaleReqConditionDto.AppTreeWorkshop(item.getWorkshopName(), item.getWorkshopCode()));
                    }
                }
            }
            boolean containsLine = AppSaleReqConditionDto.isContainsLine(result, item);
            if (!containsLine) {
                for (int j = 0; j < result.size(); j++) {
                    AppSaleReqConditionDto itemFactory = result.get(j);
                    for (int k = 0; k < itemFactory.getWorkshops().size(); k++) {
                        AppSaleReqConditionDto.AppTreeWorkshop itemWorkShop = itemFactory.getWorkshops().get(k);
                        if (itemFactory.getFactoryCode().equals(item.getFactoryCode()) && itemFactory.getFactoryName().equals(item.getFactoryName()) &&
                                itemWorkShop.getWorkshopCode().equals(item.getWorkshopCode()) && itemWorkShop.getWorkshopName().equals(item.getWorkshopName())) {
                            itemWorkShop.getLines().add(new AppSaleReqConditionDto.AppTreeLines(item.getLineName(), item.getLineCode()));
                        }
                    }
                }
            }
        }
        return result;
    }
public static boolean isContainsFactory(List<AppSaleReqConditionDto> list, AppFactoryWorkShopLineDto strDto) {
        boolean flag = false;
        if (CollectionUtils.isNotEmpty(list)) {
            for (int i = 0; i < list.size(); i++) {
                AppSaleReqConditionDto item = list.get(i);
                if (item.getFactoryCode().equals(strDto.getFactoryCode()) && item.getFactoryName().equals(strDto.getFactoryName())) {
                    flag = true;
                    break;
                }
            }
        }
        return flag;
    }
    public static boolean isContainsWorkShop(List<AppSaleReqConditionDto> list, AppFactoryWorkShopLineDto strDto) {
        boolean flag = false;
        if (CollectionUtils.isNotEmpty(list)) {
            for (int i = 0; i < list.size(); i++) {
                AppSaleReqConditionDto item = list.get(i);
                List<AppTreeWorkshop> workshops = item.getWorkshops();
                if (CollectionUtils.isNotEmpty(workshops)) {
                    for (int j = 0; j < workshops.size(); j++) {
                        AppTreeWorkshop itemWorkshop = workshops.get(j);
                        List<AppTreeLines> lines = itemWorkshop.getLines();
                        if (itemWorkshop.getWorkshopCode().equals(strDto.getWorkshopCode()) && itemWorkshop.getWorkshopName().equals(strDto.getWorkshopName())) {
                            flag = true;
                            break;
                        }
                    }

                }
            }
        }
        return flag;
    }
    public static boolean isContainsLine(List<AppSaleReqConditionDto> list, AppFactoryWorkShopLineDto strDto) {
        boolean flag = false;
        if (CollectionUtils.isNotEmpty(list)) {
            for (int i = 0; i < list.size(); i++) {
                AppSaleReqConditionDto item = list.get(i);
                List<AppTreeWorkshop> workshops = item.getWorkshops();

                if (CollectionUtils.isNotEmpty(workshops)) {
                    for (int j = 0; j < workshops.size(); j++) {
                        AppTreeWorkshop itemWorkshop = workshops.get(j);
                        List<AppTreeLines> lines = itemWorkshop.getLines();
                        if (CollectionUtils.isNotEmpty(lines)) {
                            for (int k = 0; k < lines.size(); k++) {
                                AppTreeLines line = lines.get(k);
                                if (line.getLineCode().equals(strDto.getLineCode()) && line.getLineName().equals(strDto.getLineName())) {
                                    flag = true;
                                }
                            }
                        }
                    }
                }
            }
        }
        return flag;
    }

4.平铺数据结构:

@Data
@NoArgsConstructor
@ApiModel(value = "工厂-车间-线体  平铺数据")
public class AppFactoryWorkShopLineDto {

    @ApiModelProperty(value = "工厂名字")
    private String factoryName;
    @ApiModelProperty(value = "工厂代码")
    private String factoryCode;

    @ApiModelProperty(value = "工厂-车间名字")
    private String workshopName;
    @ApiModelProperty(value = "工厂-车间代码")
    private String workshopCode;

    @ApiModelProperty(value = "线体代码")
    private String lineCode;
    @ApiModelProperty(value = "线体名称")
    private String lineName;
}

5.想要得到的数据结构:

public class AppSaleReqConditionDto {

    @ApiModelProperty(value = "工厂名字")
    private String factoryName;

    @ApiModelProperty(value = "工厂-车间数组")
    private List<AppTreeWorkshop> workshops;

    @ApiModelProperty(value = "工厂代码")
    private String factoryCode;

    public AppSaleReqConditionDto(String factoryName, String factoryCode) {
        this.factoryName = factoryName;
        this.factoryCode = factoryCode;
        this.workshops = new ArrayList<>();
    }

    @Data
    @NoArgsConstructor
    public static class AppTreeWorkshop {
        @ApiModelProperty(value = "工厂-车间名字")
        private String workshopName;

        @ApiModelProperty(value = "工厂-车间代码")
        private String workshopCode;

        @ApiModelProperty(value = "工厂-车间-线体数组")
        private List<AppTreeLines> lines;

        public AppTreeWorkshop(String workshopName, String workshopCode) {
            this.workshopName = workshopName;
            this.workshopCode = workshopCode;
            this.lines = new ArrayList<>();
        }
    }

    @Data
    @NoArgsConstructor
    public static class AppTreeLines {

        @ApiModelProperty(value = "线体代码")
        private String lineCode;

        @ApiModelProperty(value = "线体名称")
        private String lineName;

        public AppTreeLines(String lineCode, String lineName) {
            this.lineCode = lineCode;
            this.lineName = lineName;
        }
    }
  }

分析总结

树形结构处理,很自然的想到递归函数来处理,得到树形结构数据。然而非正常的上下级父子关系,递归函数显得有点苍白乏力。
单靠数据库查询条件重复带入也是可以获取到一样的数据结构,但是性能上不在一个等级。能够使用内存处理数据,不建议重复调用数据库查询。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值