java 日常开发记录

java 日常开发记录



前言

java 日常开发记录

java日常开发记录方便回查


一、java tree 树按父子关系平铺为集合(无限层级)


    @Test
    public void testSorted1() {
        List<SortedEntity> list = new ArrayList<>();
        list.add(new SortedEntity(2L, null));
        list.add(new SortedEntity(1L, null));
        list.add(new SortedEntity(3L, null));
        list.add(new SortedEntity(11L, 3L));
        list.add(new SortedEntity(10L, 3L));
        list.add(new SortedEntity(7L, 2L));
        list.add(new SortedEntity(8L, 2L));
        list.add(new SortedEntity(9L, 2L));
        list.add(new SortedEntity(4L, 1L));
        list.add(new SortedEntity(5L, 1L));
        list.add(new SortedEntity(6L, 1L));
        list.add(new SortedEntity(12L, 4L));
        list.add(new SortedEntity(13L, 4L));
        list.add(new SortedEntity(14L, 11L));
        list.add(new SortedEntity(15L, 11L));
        list.add(new SortedEntity(16L, 10L));
        list.add(new SortedEntity(17L, 13L));
        list.add(new SortedEntity(18L, 13L));
        list.add(new SortedEntity(19L, 18L));
        list.add(new SortedEntity(20L, 19L));

        Map<Long, SortedEntity> allMap = list.stream().collect(Collectors.toMap(SortedEntity::getId, Function.identity(), (s1, s2) -> s1));
        list = list.stream().sorted((x, y) -> {
            //定级
            int xLevel = getLevel(allMap, x);
            int yLevel = getLevel(allMap, y);
            //不同级别
            if(xLevel < yLevel){
                SortedEntity xlevelObj = x;
                SortedEntity yPlevelObj = getLevelObj(allMap, y, yLevel, xLevel);
                //父子关系,子比父大,非父子按同级别处理
                return xlevelObj == yPlevelObj ? -1 : sameLevelCompare(allMap,xlevelObj,yPlevelObj);
            }else if(xLevel > yLevel){
                SortedEntity ylevelObj = y;
                SortedEntity xPlevelObj = getLevelObj(allMap, x, xLevel, yLevel);
                //父子关系,子比父大,非父子按同级别处理
                return ylevelObj == xPlevelObj ? 1 :  sameLevelCompare(allMap,xPlevelObj,ylevelObj);
            }

            //同级别
            return sameLevelCompare(allMap, x, y);
        }).collect(Collectors.toList());
        System.out.println(JSON.toJSONString(list, SerializerFeature.PrettyFormat));
    }

    private int sameLevelCompare(Map<Long, SortedEntity> allMap, SortedEntity x, SortedEntity y) {
        SortedEntity xp = x, yp = y;
        while (!Objects.equals(xp.getParentId(), yp.getParentId())){
            //不同父,找同父
            SortedEntity xse = allMap.get(xp.getParentId());
            SortedEntity yse = allMap.get(yp.getParentId());
            if(Objects.equals(xse,yse)){
                //不同父id,但是都为空,即同为根节点
                break;
            }
            if(xse != null){
                xp = xse;
            }
            if(yse != null){
                yp = yse;
            }
        }

        //同父按子rank排序
        return Comparator.comparing(SortedEntity::getRank).thenComparing(SortedEntity::getId)
                .compare(xp, yp);
    }

    private SortedEntity getLevelObj(Map<Long, SortedEntity> allMap, SortedEntity c, int currLevel, int targetLevel) {
        if(targetLevel > currLevel){
            return null;
        }
        SortedEntity se = c;
        for (int level = currLevel-1; level >= targetLevel && se != null && se.getParentId() != null; level--){
            se = allMap.get(se.getParentId());
        }
        return se;
    }

    private int getLevel(Map<Long, SortedEntity> allMap, SortedEntity x) {
        if(x.getLevel() != null){
            return x.getLevel();
        }
        int level = 1;
        SortedEntity se = x;
        while (x.getParentId() != null && (se = allMap.get(se.getParentId())) != null){
            level++;
        }
        x.setLevel(level);
        return level;
    }

    @Data
    public static class SortedEntity {
    	// 主键
        private Long id;
        // 父类id,顶级父类为null
        private Long parentId;
        // 排序字段
        private Integer rank;
        //层级表示,代码中会自动计算,这里启动缓存的作用,减少循环
        private Integer level;

        public SortedEntity(Long id, Long parentId) {
            this.id = id;
            this.parentId = parentId;
            rank = RandomUtil.randomInt(1,5);
        }
    }

二、

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值