工作总结—集合转树与树的搜索(自定义搜索条件)

该博客展示了如何使用Java泛型和Stream API来处理树形结构数据,包括树的构建和搜索操作。示例代码定义了一个TreeNode接口,并提供了将扁平数据结构转换为树结构的`tree`方法,以及根据给定条件搜索树中节点的`search`方法。最后,通过一个具体的BTreeNode类实例演示了这些方法的使用。
摘要由CSDN通过智能技术生成

您需要了解

  1. Java 泛型(上下界,泛型方法)

  2. stream 流操作

  3. 递归

  4. 函数式接口

运行环境

java version "1.8.0_202"

Show me the code

定义树结构

/**
     * @param <T> 类型
     * @param <E> 元素
     */
    public interface TreeNode<T, E> extends Serializable {
        /**
         * 获取主键
         *
         * @return T
         */
        T getId();

        /**
         * 获取子级
         *
         * @return List<E>
         */
        List<E> getChild();

        /**
         * 子级设值
         *
         * @param child 子级
         */
        void setChild(List<E> child);

        /**
         * 获取父级主键
         *
         * @return T
         */
        T getParentId();
    }

树化

 /**
     * 树化
     *
     * @param source 源
     * @param <T>    类型
     * @return List<E>
     */
    public static <T, E extends TreeNode<T, E>> List<E> tree(List<E> source) {
        if (Objects.isNull(source) || source.isEmpty()) {
            return new ArrayList<>();
        }
        Map<T, E> map = source.stream().collect(Collectors.toMap(TreeNode::getId, Function.identity()));
        Set<E> root = new HashSet<>();
        source.forEach(d -> {
            T parentId = d.getParentId();
            if (map.containsKey(parentId)) {
                E parent = map.get(parentId);
                List<E> child = parent.getChild();
                if (child == null) {
                    child = new ArrayList<>();
                }
                child.add(d);
                parent.setChild(child);
                root.remove(d);
            } else {
                root.add(d);
            }
        });
        return new ArrayList<>(root);
    }

树的搜索

/**
     * 搜索树
     *
     * @param source    源
     * @param predicate 搜索条件
     * @param <T>       类型
     * @return List<E>
     */
    public static <T, E extends TreeNode<T, E>> List<E> search(List<E> source, Predicate<E> predicate) {
        List<E> target = new ArrayList<>();
        source.forEach(o -> {
            List<E> child = o.getChild();
            if (Objects.nonNull(child) && !child.isEmpty()) {
                List<E> searched = search(child, predicate);
                if (!searched.isEmpty()) {
                    o.setChild(searched);
                    target.add(o);
                } else {
                    if (predicate.test(o)) {
                        target.add(o);
                    }
                }
            } else {
                if (predicate.test(o)) {
                    target.add(o);
                }
            }
        });
        return target;
    }

使用

  /**
     * 调用示例
     *
     * @param args 参数
     */
    public static void main(String[] args) {

        class BTreeNode implements TreeNode<String, BTreeNode> {
            private String bId;
            private List<BTreeNode> bChild;
            private String bParentId;
            private String bName;

            public BTreeNode() {
            }

            public BTreeNode(String bId, String bParentId, String bName) {
                this.bId = bId;
                this.bParentId = bParentId;
                this.bName = bName;
            }

            public String getBId() {
                return bId;
            }

            public void setBId(String bId) {
                this.bId = bId;
            }

            public List<BTreeNode> getBChild() {
                return bChild;
            }

            public void setBChild(List<BTreeNode> bChild) {
                this.bChild = bChild;
            }

            public String getBParentId() {
                return bParentId;
            }

            public void setBParentId(String bParentId) {
                this.bParentId = bParentId;
            }

            public String getBName() {
                return bName;
            }

            public void setBName(String bName) {
                this.bName = bName;
            }

            @Override
            public String getId() {
                return getBId();
            }

            @Override
            public List<BTreeNode> getChild() {
                return getBChild();
            }

            @Override
            public void setChild(List<BTreeNode> child) {
                setBChild(child);
            }

            @Override
            public String getParentId() {
                return getBParentId();
            }
        }

        String id = "12";
        List<BTreeNode> source = new ArrayList<>();
        BTreeNode l11 = new BTreeNode("1", "0", "第一级");
        source.add(l11);
        BTreeNode l111 = new BTreeNode("11", "1", "第一1级");
        source.add(l111);
        BTreeNode l112 = new BTreeNode("12", "1", "第一2级");
        source.add(l112);
        BTreeNode l12 = new BTreeNode("2", "0", "第二级");
        source.add(l12);
        List<BTreeNode> dataTree = tree(source);
        List<BTreeNode> rsp = search(dataTree, bTreeNode -> Objects.equals(id, bTreeNode.getId()));
        //自定义处理
        System.out.println(rsp);
    }

完整代码

package top.mindse.word2pdf;

import java.io.Serializable;
import java.util.*;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

public class TreeNodeUtils {


    /**
     * @param <T> 类型
     * @param <E> 元素
     */
    public interface TreeNode<T, E> extends Serializable {
        /**
         * 获取主键
         *
         * @return T
         */
        T getId();

        /**
         * 获取子级
         *
         * @return List<E>
         */
        List<E> getChild();

        /**
         * 子级设值
         *
         * @param child 子级
         */
        void setChild(List<E> child);

        /**
         * 获取父级主键
         *
         * @return T
         */
        T getParentId();
    }

    /**
     * 搜索树
     *
     * @param source    源
     * @param predicate 搜索条件
     * @param <T>       类型
     * @return List<E>
     */
    public static <T, E extends TreeNode<T, E>> List<E> search(List<E> source, Predicate<E> predicate) {
        List<E> target = new ArrayList<>();
        source.forEach(o -> {
            List<E> child = o.getChild();
            if (Objects.nonNull(child) && !child.isEmpty()) {
                List<E> searched = search(child, predicate);
                if (!searched.isEmpty()) {
                    o.setChild(searched);
                    target.add(o);
                } else {
                    if (predicate.test(o)) {
                        target.add(o);
                    }
                }
            } else {
                if (predicate.test(o)) {
                    target.add(o);
                }
            }
        });
        return target;
    }


    /**
     * 树化
     *
     * @param source 源
     * @param <T>    类型
     * @return List<E>
     */
    public static <T, E extends TreeNode<T, E>> List<E> tree(List<E> source) {
        if (Objects.isNull(source) || source.isEmpty()) {
            return new ArrayList<>();
        }
        Map<T, E> map = source.stream().collect(Collectors.toMap(TreeNode::getId, Function.identity()));
        Set<E> root = new HashSet<>();
        source.forEach(d -> {
            T parentId = d.getParentId();
            if (map.containsKey(parentId)) {
                E parent = map.get(parentId);
                List<E> child = parent.getChild();
                if (child == null) {
                    child = new ArrayList<>();
                }
                child.add(d);
                parent.setChild(child);
                root.remove(d);
            } else {
                root.add(d);
            }
        });
        return new ArrayList<>(root);
    }

    /**
     * 调用示例
     *
     * @param args 参数
     */
    public static void main(String[] args) {

        class BTreeNode implements TreeNode<String, BTreeNode> {
            private String bId;
            private List<BTreeNode> bChild;
            private String bParentId;
            private String bName;

            public BTreeNode() {
            }

            public BTreeNode(String bId, String bParentId, String bName) {
                this.bId = bId;
                this.bParentId = bParentId;
                this.bName = bName;
            }

            public String getBId() {
                return bId;
            }

            public void setBId(String bId) {
                this.bId = bId;
            }

            public List<BTreeNode> getBChild() {
                return bChild;
            }

            public void setBChild(List<BTreeNode> bChild) {
                this.bChild = bChild;
            }

            public String getBParentId() {
                return bParentId;
            }

            public void setBParentId(String bParentId) {
                this.bParentId = bParentId;
            }

            public String getBName() {
                return bName;
            }

            public void setBName(String bName) {
                this.bName = bName;
            }

            @Override
            public String getId() {
                return getBId();
            }

            @Override
            public List<BTreeNode> getChild() {
                return getBChild();
            }

            @Override
            public void setChild(List<BTreeNode> child) {
                setBChild(child);
            }

            @Override
            public String getParentId() {
                return getBParentId();
            }
        }

        String id = "12";
        List<BTreeNode> source = new ArrayList<>();
        BTreeNode l11 = new BTreeNode("1", "0", "第一级");
        source.add(l11);
        BTreeNode l111 = new BTreeNode("11", "1", "第一1级");
        source.add(l111);
        BTreeNode l112 = new BTreeNode("12", "1", "第一2级");
        source.add(l112);
        BTreeNode l12 = new BTreeNode("2", "0", "第二级");
        source.add(l12);
        List<BTreeNode> dataTree = tree(source);
        List<BTreeNode> rsp = search(dataTree, bTreeNode -> Objects.equals(id, bTreeNode.getId()));
        //自定义处理
        System.out.println(rsp);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值