All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ars.util.Trees Maven / Gradle / Ivy

The newest version!
package ars.util;

import java.util.Map;
import java.util.List;
import java.util.Arrays;
import java.util.Map.Entry;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.Collection;
import java.util.LinkedHashMap;

/**
 * 树工具类
 *
 * @author wuyongqiang
 */
public final class Trees {
    private Trees() {

    }

    /**
     * 获取树最大深度
     *
     * @param   数据类型
     * @param tree 树对象实例
     * @return 树深度
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    public static  int getDepth(M tree) {
        if (tree == null) {
            return 0;
        }
        List children = tree.getChildren();
        if (children.isEmpty()) {
            return 1;
        }
        int depth = 0;
        for (int i = 0; i < children.size(); i++) {
            int _depth = getDepth(children.get(i));
            if (_depth > depth) {
                depth = _depth;
            }
        }
        return depth + 1;
    }

    /**
     * 获取树最大宽度
     *
     * @param   数据类型
     * @param tree 树对象实例
     * @return 树宽度
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    public static  int getWidth(M tree) {
        if (tree == null) {
            return 0;
        }
        List children = tree.getChildren();
        if (children.isEmpty()) {
            return 1;
        }
        int width = 0;
        for (int i = 0; i < children.size(); i++) {
            width += getWidth(children.get(i));
        }
        return width;
    }

    /**
     * 获取树层级(从1开始)
     *
     * @param   数据类型
     * @param tree 树对象实例
     * @return 树层级
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    public static  int getLevel(M tree) {
        if (tree == null) {
            return 0;
        }
        int level = 1;
        M parent = (M) tree.getParent();
        while (parent != null) {
            level++;
            parent = (M) parent.getParent();
        }
        return level;
    }

    /**
     * 判断树对象是否是环形对象
     *
     * @param   数据类型
     * @param tree 树对象实例
     * @return true/false
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    public static  boolean isLoop(M tree) {
        if (tree == null) {
            return false;
        }
        M parent = (M) tree.getParent();
        while (parent != null) {
            if (tree.equals(parent)) {
                return true;
            }
            parent = (M) parent.getParent();
        }
        return false;
    }

    /**
     * 获取树对象根节点
     *
     * @param   数据类型
     * @param tree 树对象实例
     * @return 树对象实例
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    public static  M getRoot(M tree) {
        if (tree == null) {
            return null;
        }
        M parent = null;
        while ((parent = (M) tree.getParent()) != null) {
            tree = parent;
        }
        return tree;
    }

    /**
     * 获取树对象所有父节点
     *
     * @param   数据类型
     * @param tree 树对象实例
     * @return 父节点实例列表
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    public static  List getParents(M tree) {
        M parent = null;
        if (tree == null || (parent = (M) tree.getParent()) == null) {
            return new ArrayList(0);
        }
        LinkedList parents = new LinkedList();
        while (parent != null) {
            parents.addFirst(parent);
            parent = (M) parent.getParent();
        }
        return parents;
    }

    /**
     * 获取树对象所有父节点
     *
     * @param    数据类型
     * @param trees 树对象实例数组
     * @return 父节点实例列表
     */
    @SuppressWarnings("rawtypes")
    public static  List getParents(M[] trees) {
        return trees == null || trees.length == 0 ? new ArrayList(0) : getParents(Arrays.asList(trees));
    }

    /**
     * 获取树对象所有父节点
     *
     * @param    数据类型
     * @param trees 树对象实例集合
     * @return 父节点实例列表
     */
    @SuppressWarnings({"rawtypes", "unchecked"})
    public static  List getParents(Collection trees) {
        if (trees == null || trees.isEmpty()) {
            return new ArrayList(0);
        }
        List parents = new LinkedList();
        for (M tree : trees) {
            M parent = (M) tree.getParent();
            while (parent != null) {
                if (!parents.contains(parent)) {
                    parents.add(parent);
                }
                parent = (M) parent.getParent();
            }
        }
        return parents;
    }

    /**
     * 获取树对象所有叶节点
     *
     * @param   数据类型
     * @param tree 树对象实例
     * @return 树对象列表
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    public static  List getLeaves(M tree) {
        if (tree == null) {
            return new ArrayList(0);
        }
        List leaves = new LinkedList();
        List children = tree.getChildren();
        if (children.isEmpty()) {
            leaves.add(tree);
        } else {
            for (int i = 0; i < children.size(); i++) {
                leaves.addAll(getLeaves((M) children.get(i)));
            }
        }
        return leaves;
    }

    /**
     * 获取树对象所有叶节点
     *
     * @param    数据类型
     * @param trees 树对象数组
     * @return 树对象列表
     */
    @SuppressWarnings("rawtypes")
    public static  List getLeaves(M[] trees) {
        return trees == null || trees.length == 0 ? new ArrayList(0) : getLeaves(Arrays.asList(trees));
    }

    /**
     * 获取树对象所有叶节点
     *
     * @param    数据类型
     * @param trees 树对象集合
     * @return 树对象列表
     */
    @SuppressWarnings("rawtypes")
    public static  List getLeaves(Collection trees) {
        if (trees == null || trees.isEmpty()) {
            return new ArrayList(0);
        }
        List leaves = new LinkedList();
        for (M tree : trees) {
            leaves.addAll(getLeaves(tree));
        }
        return leaves;
    }

    /**
     * 获取树展开列表
     *
     * @param   数据类型
     * @param tree 树对象实例
     * @return 树对象列表
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    public static  List getExpands(M tree) {
        if (tree == null) {
            return new ArrayList(0);
        }
        List expands = new LinkedList();
        expands.add(tree);
        List children = tree.getChildren();
        for (int i = 0; i < children.size(); i++) {
            expands.addAll(getExpands((M) children.get(i)));
        }
        return expands;
    }

    /**
     * 获取树展开列表
     *
     * @param    数据类型
     * @param trees 树对象数组
     * @return 树对象列表
     */
    @SuppressWarnings("rawtypes")
    public static  List getExpands(M[] trees) {
        return trees == null || trees.length == 0 ? new ArrayList(0) : getExpands(Arrays.asList(trees));
    }

    /**
     * 获取树展开列表
     *
     * @param    数据类型
     * @param trees 树对象集合
     * @return 树对象列表
     */
    @SuppressWarnings("rawtypes")
    public static  List getExpands(Collection trees) {
        if (trees == null || trees.isEmpty()) {
            return new ArrayList(0);
        }
        List expands = new LinkedList();
        for (M tree : trees) {
            expands.addAll(getExpands(tree));
        }
        return expands;
    }

    /**
     * 合并树
     *
     * @param    数据类型
     * @param trees 树数组
     * @return 合并后的树列表
     */
    @SuppressWarnings("rawtypes")
    public static  List getMerges(M[] trees) {
        return trees == null || trees.length == 0 ? new ArrayList(0) : getMerges(Arrays.asList(trees));
    }

    /**
     * 合并树
     *
     * @param    数据类型
     * @param trees 树集合
     * @return 合并后的树列表
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    public static  List getMerges(Collection trees) {
        if (trees == null || trees.isEmpty()) {
            return new ArrayList(0);
        }
        Map> temp = new LinkedHashMap>();
        for (M tree : trees) {
            if (!temp.containsKey(tree)) {
                temp.put(tree, new ArrayList());
            }
            M parent = (M) tree.getParent();
            if (parent != null && trees.contains(parent)) {
                List children = temp.get(parent);
                if (children == null) {
                    children = new ArrayList();
                    temp.put(parent, children);
                }
                children.add(tree);
            }
        }
        List roots = new ArrayList(trees.size());
        for (Entry> entry : temp.entrySet()) {
            M key = entry.getKey();
            key.setChildren(entry.getValue());
            M parent = (M) key.getParent();
            if (parent == null || !temp.containsKey(parent)) {
                roots.add(key);
            }
        }
        return roots;
    }

    /**
     * 比较两个树对象数组是否相同
     *
     * @param     数据类型
     * @param trees  树对象数组
     * @param _trees 树对象数组
     * @return true/false
     */
    @SuppressWarnings("rawtypes")
    public static  boolean isEqual(M[] trees, M[] _trees) {
        return trees == _trees || (trees != null && _trees != null && trees.length == 0 && _trees.length == 0)
            || isEqual(Arrays.asList(trees), Arrays.asList(_trees));
    }

    /**
     * 比较两个树对象数组是否相同
     *
     * @param         数据类型
     * @param trees      树对象数组
     * @param _trees     树对象数组
     * @param comparator 比较器对象
     * @return true/false
     */
    @SuppressWarnings("rawtypes")
    public static  boolean isEqual(M[] trees, M[] _trees, Comparator comparator) {
        return trees == _trees || (trees != null && _trees != null && trees.length == 0 && _trees.length == 0)
            || isEqual(Arrays.asList(trees), Arrays.asList(_trees), comparator);
    }

    /**
     * 比较两个树对象集合是否相同
     *
     * @param     数据类型
     * @param trees  树对象集合
     * @param _trees 树对象集合
     * @return true/false
     */
    @SuppressWarnings("rawtypes")
    public static  boolean isEqual(Collection trees, Collection _trees) {
        return isEqual(trees, _trees, new Comparator() {

            @Override
            public int compare(M o1, M o2) {
                return o1.equals(o2) ? 0 : -1;
            }

        });
    }

    /**
     * 比较两个树对象集合是否相同
     *
     * @param         数据类型
     * @param trees      树对象集合
     * @param _trees     树对象集合
     * @param comparator 比较器对象
     * @return true/false
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    public static  boolean isEqual(Collection trees, Collection _trees,
                                                   Comparator comparator) {
        if (trees == _trees || (trees != null && _trees != null && trees.isEmpty() && _trees.isEmpty())) {
            return true;
        }
        for (M tree : trees) {
            M _tree = null;
            for (M m : _trees) {
                if (comparator.compare(tree, m) == 0) {
                    _tree = m;
                    break;
                }
            }
            boolean found = _tree == null ? false : isEqual(tree.getChildren(), _tree.getChildren(), comparator);
            if (!found) {
                return false;
            }
        }
        for (M _tree : _trees) {
            M tree = null;
            for (M m : trees) {
                if (comparator.compare(_tree, m) == 0) {
                    tree = m;
                    break;
                }
            }
            boolean found = tree == null ? false : isEqual(_tree.getChildren(), tree.getChildren(), comparator);
            if (!found) {
                return false;
            }
        }
        return true;
    }

    /**
     * 串联所有父节点字符串
     *
     * @param   数据类型
     * @param tree 树对象实例
     * @param sign 连接标记
     * @return 当前节点及所有父节点字符串串联
     */
    @SuppressWarnings("rawtypes")
    public static  String toString(M tree, CharSequence sign) {
        return toString(tree, sign, 0, false);
    }

    /**
     * 串联所有父节点字符串
     *
     * @param      数据类型
     * @param tree    树对象实例
     * @param sign    连接标记
     * @param reverse 是否反转顺序
     * @return 当前节点及所有父节点字符串串联
     */
    @SuppressWarnings("rawtypes")
    public static  String toString(M tree, CharSequence sign, boolean reverse) {
        return toString(tree, sign, 0, reverse);
    }

    /**
     * 串联所有父节点字符串
     *
     * @param    数据类型
     * @param tree  树对象实例
     * @param sign  连接标记
     * @param depth 连接深度(从1开始,小于1标识不限制深度)
     * @return 当前节点及所有父节点字符串串联
     */
    @SuppressWarnings("rawtypes")
    public static  String toString(M tree, CharSequence sign, int depth) {
        return toString(tree, sign, depth, false);
    }

    /**
     * 串联所有父节点字符串
     *
     * @param      数据类型
     * @param tree    树对象实例
     * @param sign    连接标记
     * @param depth   连接深度(从1开始,小于1标识不限制深度)
     * @param reverse 是否反转顺序
     * @return 当前节点及所有父节点字符串串联
     */
    @SuppressWarnings("rawtypes")
    public static  String toString(M tree, CharSequence sign, int depth, boolean reverse) {
        if (tree == null || sign == null) {
            return null;
        }
        int level = 1;
        StringBuilder buffer = new StringBuilder(tree.toString());
        Tree parent = tree.getParent();
        while (parent != null && (depth < 1 || level++ < depth)) {
            if (reverse) {
                buffer.append(sign);
                buffer.append(parent.toString());
            } else {
                buffer.insert(0, sign);
                buffer.insert(0, parent.toString());
            }
            parent = parent.getParent();
        }
        return buffer.toString();
    }

    /**
     * 获取多个树对象第一个共同父节点
     *
     * @param    数据类型
     * @param trees 树对象数组
     * @return 树对象
     */
    @SuppressWarnings("rawtypes")
    public static  M getAncestor(M[] trees) {
        return getAncestor(trees, new Comparator() {

            @Override
            public int compare(M o1, M o2) {
                return o1.equals(o2) ? 0 : -1;
            }

        });
    }

    /**
     * 获取多个树对象第一个共同父节点
     *
     * @param         数据类型
     * @param trees      树对象数组
     * @param comparator 对象比较器
     * @return 树对象
     */
    @SuppressWarnings({"rawtypes", "unchecked"})
    public static  M getAncestor(M[] trees, Comparator comparator) {
        if (trees == null || trees.length == 0) {
            return null;
        }
        M intersect = trees[0];
        outer:
        for (int i = 1; i < trees.length; i++) {
            while (intersect != null) {
                M tree = trees[i];
                while (tree != null) {
                    if (comparator.compare(intersect, tree) == 0) {
                        continue outer;
                    }
                    tree = (M) tree.getParent();
                }
                intersect = (M) intersect.getParent();
            }
            return null;
        }
        return intersect;
    }

    /**
     * 获取多个树对象第一个共同父节点
     *
     * @param    数据类型
     * @param trees 树对象集合
     * @return 树对象
     */
    @SuppressWarnings("rawtypes")
    public static  M getAncestor(Collection trees) {
        return getAncestor(trees, new Comparator() {

            @Override
            public int compare(M o1, M o2) {
                return o1.equals(o2) ? 0 : -1;
            }

        });
    }

    /**
     * 获取多个树对象第一个共同父节点
     *
     * @param         数据类型
     * @param trees      树对象集合
     * @param comparator 对象比较器
     * @return 树对象
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    public static  M getAncestor(Collection trees, Comparator comparator) {
        return trees == null || trees.isEmpty() ? null
            : getAncestor((M[]) trees.toArray(Beans.getArray(trees.iterator().next().getClass(), 0)), comparator);
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy