范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

摸鱼三天!我写了一个通用的组建树TreeUtil工具

  1. 树的简单遍历思路及写法①数据准备
  Menu实体类/** * @date: 2022/7/25 * @FileName: Menu * @author: Yan * @Des: */@Data@AllArgsConstructor@NoArgsConstructorpublic class Menu {    private Integer id;    private String name;    private Integer parentId;    private List children;    public Menu(Integer id, String name, Integer parentId) {        this.id = id;        this.name = name;        this.parentId = parentId;    }}复制代码
  创建测试数据List/** * @date: 2022/7/25 * @FileName: TreeController * @author: Yan * @Des: */@RestController@RequestMapping("/tree")public class TreeController {    public static List getMenus(){        List menus = Arrays.asList(                new Menu(1, "A公司", 0),                new Menu(2, "a销售部", 14),                new Menu(3, "财税部", 1),                new Menu(4, "商务部", 1),                new Menu(5, "综合部", 1),                new Menu(6, "a销售1部", 2),                new Menu(7, "a销售2部", 2),                new Menu(8, "a销售3部", 2),                new Menu(9, "a销售4部", 2),                new Menu(10, "b销售部", 14),                new Menu(11, "b销售1部", 10),                new Menu(12, "b销售2部", 10),                new Menu(13, "人事部", 1),                new Menu(14, "销售部", 1));        return menus;    }}复制代码② 使用Lambda的语法糖遍历及制作树
  在TreeController中,写入:    @RequestMapping    public List getTree(){        List menus = getMenus();        List menusTree = menus.stream()                .filter(menu -> menu.getParentId() == 0)                .map(menu -> {                    menu.setChildren(getChildrens(menu, menus));                    return menu;                })                .collect(Collectors.toList());        return menusTree;    }        public static List getChildrens(Menu root, List allMenus){        List childrenTree = allMenus.stream()                .filter(menu -> Objects.equals(menu.getParentId(), root.getId()))                .peek(menu -> menu.setChildren(getChildrens(menu, allMenus)))                .collect(Collectors.toList());        return childrenTree;    }复制代码③ 查看运行结果
  可以看到,我们成功的返回了树形结构
  问题的出现
  最近看公司项目,经常会碰到一些场景是需要以树形结构展示的,比如说部门树,设备树,分类树等等,但是感觉好像都是需要用到的时候现写的,但是大体的思路是一样的,感觉重复写就有点冗余了,而且对应的树形结构构建又相对麻烦,我就想着抽离一下,做成一个通用的工具类TreeUtil,于是翻了一下别的大佬的文章,学着写了这样的一个工具类。问题的解决2. 制作工具2.1 TreeNode接口
  TreeNode用来表示每个树节点的抽象,即需要生成树的对象需要实现此接口。/** * @date: 2022/7/25 * @FileName: TreeNode * @author: Yan * @Des: 树节点父类,所有需要使用TreeUtils工具类形成树形结构等操作的节点都需要实现该接口 */public interface TreeNode {    /**     * 获取树结点id     * @return     */    T getTreeNodeId();    /**     * 获取该节点的父节点id     * @return     */    T getParentId();    /**     * 判断该节点是否为根节点,默认判定     * @Des 可以用于简单树的组件     * @return     */    boolean isRoot();    /**     * 自定义父结点的判定规则     * @param rootCondition     * @return     */    boolean isRoot(RC rootCondition);    /**     * 自定义子节点(叶子结点)的判定规则     * @param leafCondition     * @return     */    boolean isChildren(LC leafCondition);    /**     * 判断是否有子节点     * @return     */    boolean hasChild();    /**     * 设置结点的子节点列表     * @param children     */    void setChildren(List<? extends TreeNode> children);    /**     * 获取所有子节点     * @return     */    List<? extends TreeNode> getChildren();    /**     * 获取树的深度     * @return     */    Integer getLevel();    /**     * 设置树的深度     */    void setLevel(Integer level);}复制代码泛型说明:
  T 主要定义返回值的类型
  RC(rootCondition) 主要是定义根节点 (也就是父节点) 的自定义判定规则需要用到的参数类型
  LC(leafCondition) 主要是定义叶子结点(也就是子节点)的自定义判定规则需要用到的参数类型2.2 TreeUtil工具类回调函数——函数式接口
  用于遍历树作自定义操作使用/** * @date: 2022/7/28 * @FileName: Handle * @author: Yan * @Des:    定义一个函数式接口 */@FunctionalInterfacepublic interface FunctionHandle  {        void callback(N node, Map result);}复制代码泛型说明:
  N 表示传入回调函数的结点参数类型
  K 表示结果集的key
  V 表示结果集的value非Lambda表达式写法( 适用于所有版本)/** * @date: 2022/7/25 * @FileName: TreeUtils * @author: Yan * @Des: TreeUtils用来生成树形结构,以及获取所有叶子节点等操作 */public class TreeUtils {    /**     * 根据所有树节点列表,按默认条件生成含有所有树形结构的列表     * 主要用于组建简单树形结构     * @param allData 树形节点列表     * @param    节点类型     * @return 树形结构列表     */    public static > List generateTrees(List allData) {        List roots = new ArrayList<>();        // 使用迭代器操作list元素        for (Iterator iterator = allData.iterator(); iterator.hasNext(); ) {            E node = iterator.next();            if (node.isRoot()) {                node.setLevel(0);                // 获取所有的根节点                roots.add(node);                // 从所有节点列表中删除该节点,以免后续重复遍历该节点                iterator.remove();            }        }        roots.forEach(r -> {            getChildren(r, allData);        });        return roots;    }    /**     * 根据所有树节点列表,按自定义条件---->获取符合条件的父节点     * @param allData   所有树形结构结点     * @param rootCondition 父节点的判定规则     * @param  结点类型     * @param  父节点自定义判定方法的参数类型     * @return 按自定义条件获取符合条件的父节点     */    public static , RC> List generateTrees(List allData, RC rootCondition) {        List roots = new ArrayList<>();        // 使用迭代器操作list元素        for (Iterator iterator = allData.iterator(); iterator.hasNext(); ) {            E node = iterator.next();            // 按条件筛选根节点            if (node.isRoot(rootCondition)) {                node.setLevel(0);                // 获取所有的根节点                roots.add(node);                // 从所有节点列表中删除该节点,以免后续重复遍历该节点                iterator.remove();            }        }        // 返回按条件查询到的父节点        return roots;    }    /**     * 给父节点填充叶子结点     * @param parent    父节点     * @param nodes 所有结点集合     * @param    父节点的对象类型     * @param    集合的类型     */    @SuppressWarnings("all")    public static  void getChildren(T parent, List allData) {        List children = new ArrayList<>();        for (Iterator ite = allData.iterator(); ite.hasNext(); ) {            E node = ite.next();            // 找出与当前父节点关联的叶子结点            if (Objects.equals(node.getParentId(), parent.getTreeNodeId())) {                node.setLevel(parent.getLevel() + 1);                children.add(node);                // 从所有节点列表中删除该节点,以免后续重复遍历该节点                ite.remove();            }        }        System.out.println(children);        // 如果孩子为空,则直接返回,否则继续递归设置孩子的孩子        if (children.isEmpty()) {            return;        }        parent.setChildren(children);        // 继续递归叶子结点的遍历子节点        children.forEach(m -> {            // 递归设置子节点            getChildren(m, allData);        });    }    /**     * 按照自定义的规则,给父节点填充叶子结点     * @param parent    父节点     * @param allData   所有树形结构结点     * @param leafConfition 叶子结点的自定义判定规则的参数类型     * @param    父节点对象类型     * @param    集合类型     * @param   参数类型     */    @SuppressWarnings("all")    public static , LC> void getChildren(T parent, List allData, LC leafConfition) {        List children = new ArrayList<>();        Object parentId = parent.getTreeNodeId();        for (Iterator ite = allData.iterator(); ite.hasNext(); ) {            E node = ite.next();            // 按自定义条件筛选子节点,null则表示没有自定义条件            if (Objects.isNull(leafConfition) || node.isChildren(leafConfition)){                // 找出与当前父节点关联的叶子结点                if (Objects.equals(node.getParentId(), parentId)) {                    node.setLevel(parent.getLevel() + 1);                    children.add(node);                    // 从所有节点列表中删除该节点,以免后续重复遍历该节点                    ite.remove();                }            }        }        // 如果孩子为空,则直接返回,否则继续递归设置孩子的孩子        if (children.isEmpty()) {            return;        }        parent.setChildren(children);        // 继续递归叶子结点的遍历子节点        children.forEach(m -> {            // 递归设置子节点            getChildren(m, allData);        });    }    /**     * 根据获取特定结点的子树,通过isParent来判断是否需要父节点     * @param root  根节点(子节点)     * @param allData   全部结点数据     * @param isParent  是否需要父节点     * @param    结点的对象类型     * @return     */    public static > List getTreeByNode(T root, List allData, boolean isParent){        List tree = new ArrayList<>();        if (isParent){            root.setLevel(0);            tree.add(root);            // 包含父节点            // 填充叶子结点            tree.forEach(child -> getChildren(child, allData));            return tree;        } else {            // 不含父节点            // 填充叶子结点            getChildren(root, allData);            return root.getChildren();        }    }    public static void main(String[] args) {        Boolean test = null;    }    /**     * 根据获取特定结点的子树,通过isParent来判断是否需要父节点,通过leafConfition来按照自定义的规则给父节点填充子节点     * @param root  根节点(子节点)     * @param allData   全部结点数据     * @param isParent  是否需要父节点     * @param leafCondition 定义叶子结点的判定参数     * @param    结点的对象类型     * @param   自定义叶子结点的判定参数的对象类型     * @return     */    public static , LC> List getTreeByNode(T root, List allData, boolean isParent, LC leafCondition){        List tree = new ArrayList<>();        if (isParent){            root.setLevel(0);            tree.add(root);            // 包含父节点            // 填充叶子结点            tree.forEach(child -> getChildren(child, allData, leafCondition));            return tree;        } else {            // 不含父节点            // 填充叶子结点            getChildren(root, allData, leafCondition);            return root.getChildren();        }    }    /**     * 根据结点id获取特定结点的子树,通过isParent来判断是否需要父节点     * @param rootId    结点id     * @param allData   所有结点数据     * @param isParent  是否需要父结点     * @param    结点id的对象类型     * @param    集合的类型     * @return     */    public static > List getTreeByNodeId(T rootId, List allData, boolean isParent){        List tree = new ArrayList<>();        E root = null;        for (Iterator iterator = allData.iterator(); iterator.hasNext(); ){            E node = iterator.next();            if (rootId.equals(node.getTreeNodeId())){                node.setLevel(0);                tree.add(node);                root = node;                iterator.remove();            }        }        System.out.println(root);        // 是否需要父节点        if (isParent){            // 需要父节点            // 填充叶子结点            tree.forEach(child -> getChildren(child, allData));            return tree;        } else {            // 不需要父节点            // 填充叶子结点            getChildren(root, allData);            return root.getChildren();        }    }    /**     * 根据结点id获取特定结点的子树,通过isParent来判断是否需要父节点     * @param rootId    结点id     * @param allData   所有结点数据     * @param isParent  是否需要父结点     * @param leafCondition 定义叶子结点的判定参数     * @param    结点id的对象类型     * @param    集合的类型     * @param   自定义叶子结点的判定参数的对象类型     * @return     */    public static , LC> List getTreeByNodeId(T rootId, List allData, boolean isParent, LC leafCondition){        List tree = new ArrayList<>();        E root = null;        for (Iterator iterator = allData.iterator(); iterator.hasNext(); ){            E node = iterator.next();            if (Objects.equals(rootId, node.getTreeNodeId())){                root.setLevel(0);                tree.add(node);                root = node;                iterator.remove();            }        }        System.out.println(root);        // 是否需要父节点        if (isParent){            // 需要父节点            // 填充叶子结点            tree.forEach(child -> getChildren(child, allData, leafCondition));            return tree;        } else {            // 不需要父节点            // 填充叶子结点            getChildren(root, allData, leafCondition);            return root.getChildren();        }    }    /**     * 遍历树型结构,并且根据回调函数执行相应的操作处理     * @param tree  树     * @param handle    回调函数     * @param    集合类型     * @param    结果集的key     * @param    结果集的value     * @return  返回一个结果集的map     */    public static , K, V> Map traverseTree(List tree, FunctionHandle handle){        Map resultMap = new HashMap<>();        for (Iterator iterator = tree.iterator(); iterator.hasNext(); ){            E node = iterator.next();            if (handle != null){                handle.callback(node, resultMap);            }            if (node.hasChild()){                recursiveTree(node.getChildren(), resultMap, handle);            }        }        return resultMap;    }    /**     * 递归遍历子树,获取相应的处理结果     * @param children  子树集合     * @param resultMap 结果集     * @param handle    回调函数     * @param    集合类型     */    public static > void recursiveTree(List children, Map resultMap, FunctionHandle handle){        for (Iterator iterator = children.iterator(); iterator.hasNext(); ){            E child = iterator.next();            if (handle != null){                handle.callback(child, resultMap);            }            if (child.hasChild()){                recursiveTree(child.getChildren(), resultMap, handle);            }        }    }}复制代码3. 使用工具① 定义一个类,实现TreeNode接口
  这里以树形菜单Menu为例
  根据Menu类创建一个属性一样的的MenuVo类,并且实现TreeNode接口,通过对TreeNode接口方法的实现来让MenuVo变成一个树形节点。/** * @date: 2022/7/26 * @FileName: MenuVo * @author: Yan * @Des: */@Datapublic class MenuVo implements TreeNode {    private Integer id;    private String name;    private Integer parentId;    private Integer Level;    private List children;    public MenuVo(Integer id, String name, Integer parentId) {        this.id = id;        this.name = name;        this.parentId = parentId;    }    @Override    public Integer getTreeNodeId() {        return this.id;    }    @Override    public Integer getParentId() {        return this.parentId;    }    @Override    public boolean isRoot() {        // 默认判定        return Objects.equals(this.parentId, 0);    }    @Override    public boolean isRoot(Boolean rootCondition) {        // 自定义的父节点判定规则        if (rootCondition){            return Objects.equals(this.id, 14);        } else {            // 都不符合就走默认判定条件            return isRoot();        }    }    @Override    public boolean isChildren(Integer leafCondition) {        // 自定义结点判定规则        // 这里自定义规则当传入的参数等于1的时候 ——> 要销售部,只要销售部的带有"a"的部门名作为子树节点        if (leafCondition.equals(1)){            if (this.name.contains("a")){                return true;            } else {                return false;            }        } else {            // 都不符合就表示该节点不是自定义规则中要的结点            return false;        }    }    @Override    public boolean hasChild() {        return !Objects.isNull(this.children);    }    @Override    public void setChildren(List children) {        this.children = children;    }    @Override    public List getChildren(){        return this.children;    }}复制代码② 数据准备    // 获取测试数据    public static List getMenusVo(){        List menus = Arrays.asList(                new MenuVo(1, "A公司", 0),                new MenuVo(2, "a销售部", 14),                new MenuVo(3, "财税部", 1),                new MenuVo(4, "商务部", 1),                new MenuVo(5, "综合部", 1),                new MenuVo(6, "a销售1部", 2),                new MenuVo(7, "a销售2部", 2),                new MenuVo(8, "a销售3部", 2),                new MenuVo(9, "a销售4部", 2),                new MenuVo(10, "b销售部", 14),                new MenuVo(11, "b销售1部", 10),                new MenuVo(12, "b销售2部", 10),                new MenuVo(13, "人事部", 1),                new MenuVo(14, "销售部", 1));        return menus;    }复制代码③ 按照业务需求进行使用
  创建一个Controller,发送相应的请求,查看返回结果    @GetMapping("/test")    public List getTree2(){        List menusVoList = new ArrayList<>(Arrays.asList(                new MenuVo(1, "A公司", 0),                new MenuVo(2, "a销售部", 14),                new MenuVo(3, "财税部", 1),                new MenuVo(4, "商务部", 1),                new MenuVo(5, "综合部", 1),                new MenuVo(6, "a销售1部", 2),                new MenuVo(7, "a销售2部", 2),                new MenuVo(8, "a销售3部", 2),                new MenuVo(9, "a销售4部", 2),                new MenuVo(10, "b销售部", 14),                new MenuVo(11, "b销售1部", 10),                new MenuVo(12, "b销售2部", 10),                new MenuVo(13, "人事部", 1),                new MenuVo(14, "销售部", 1)));        // 组装树形结构        List menuVotree = TreeUtils.generateTrees(menusVoList);                // 遍历树,回调处理得出相应结果        Map result = TreeUtils.traverseTree(menuVotree, (treeNode, resultMap) -> {            if (treeNode.getName().contains("a")) {                resultMap.put(treeNode.getTreeNodeId(), treeNode.getName());            }        });        List objects = new ArrayList<>();        objects.add(result);        // 按自定义条件组装树//        List menuVoTreeByCondition = TreeUtils.generateTrees(menusVoList,true);//        menuVoTreeByCondition.forEach(node -> TreeUtils.getChildren(node, menusVoList, 1));        // 获取对应结点的子树,true表示要留有父节点,false表示不留不父节点//        List childTreeByParent = TreeUtils.getTreeByNode(new MenuVo(14, "销售部", 1), menusVoList, true);          // 通过父节点id获取其子树,true表示要留有父节点,false表示不留不父节点//        List treeNodesList = TreeUtils.getTreeByNodeId(14, menusVoList, true);        return objects;    }复制代码4. TreeUtil工具类的api介绍① 简单组装树
  按照默认条件,简单将所有的结点组装成树// 组装树形结构List menuVotree = TreeUtils.generateTrees(menusVoList);复制代码
  运行结果
  ② 按自定义条件组装树
  按照自定义条件,将结点列表组装成树
  获取id为14,切子部门中名字带有"a"的子部门// 按自定义条件组装树// 步骤① 按照自定义的规则筛选父节点List menuVoTreeByCondition = TreeUtils.generateTrees(menusVoList,true);// 步骤② 将得到的父节点按自定义的子节点判定规则填充子节点menuVoTreeByCondition.forEach(node -> TreeUtils.getChildren(node, menusVoList, 1));复制代码步骤① 这里可以看NodeTree的实现类的IsRoot方法说明,我为了测试,自定义的条件为要id=14的结点为父节点步骤② 这里按条件给父节点填充子节点的判定规则是自定义的,在isChildren中有相应的判定,我这里为了测试:自定义规则当传入的参数等于1的时候 ——> 要销售部,只要销售部的带有"a"的部门名作为子树节点
  运行结果
  ③ 按结点获取对应子树集合
  根据结点获取子树,true表示要留有父节点,false表示不留不父节点// 根据树形结构,获取对应树节点的子节点 List childTreeByParent = TreeUtils.getTreeByNode(new MenuVo(14, "销售部", 1), menusVoList, true);复制代码
  运行结果
  ④ 按结点id获取对应的子树集合
  通过父节点id获取其子树,true表示要留有父节点,false表示不留不父节点// 通过父节点id获取其子树,true表示要留有父节点,false表示不留不父节点List treeNodesList = TreeUtils.getTreeByNodeId(14, menus, true);复制代码
  运行结果
  ⑤ 遍历树的同时做自定义操作
  遍历树型结构的同时,做相应的自定义操作
  找出部门名字含有或者b的部门名,存入结果集并返回// 组装树形结构List menuVotree = TreeUtils.generateTrees(menusVoList);// 遍历树,回调处理得出相应结果Map result = TreeUtils.traverseTree(menuVotree, (treeNode, resultMap) -> {    // 找出部门名字含有或者b的部门名,存入结果集并返回    if (treeNode.getName().contains("b")) {    resultMap.put(treeNode.getTreeNodeId(), treeNode.getName());    }});复制代码
  运行结果
  统计各个部门的子部门数// 组装树形结构List menuVotree = TreeUtils.generateTrees(menusVoList);// 遍历树,回调处理得出相应结果Map result = TreeUtils.traverseTree(menuVotree, (treeNode, resultMap) -> {    if (!treeNode.hasChild()){        if (treeNode.getName().contains("销售")){            resultMap.put("销售部", resultMap.get("销售部") == null ? 1 : resultMap.get("销售部") + 1);        }        if (treeNode.getName().contains("财税")){            resultMap.put("财税部", resultMap.get("财税部") == null ? 1 : resultMap.get("财税部") + 1);        }        if (treeNode.getName().contains("商务")){            resultMap.put("商务部", resultMap.get("商务部") == null ? 1 : resultMap.get("商务部") + 1);        }        if (treeNode.getName().contains("综合")){            resultMap.put("综合部", resultMap.get("综合部") == null ? 1 : resultMap.get("综合部") + 1);        }    }});复制代码
  运行结果
  作者:我是你下药都得不到的男人
  链接:https://juejin.cn/post/7125354593982087199
  来源:稀土掘金
  著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
如何理解新能源时代的电力运营商?导语新能源发电可能是一个目前数千亿,在2025年一两万亿,2060年十几万亿规模,复合增长率10属于成长性不低,确定性较高,规模极大的行业。1行业电力是一个令人感到有些无趣很大的行券商2022年业绩普遍下滑龙头营收净利双降,两家逆势增长2023年开年以来,证券行业进入年报披露季。春节长假后,又有上市券商交卷。西部证券中泰证券日前发布了2022年业绩预告。据Wind数据,截至目前,中信证券国元证券披露了2022年业2022年三季度银行业消费投诉逾7万件,信用卡业务占5成1月30日,中国银保监会消费者权益保护局发布关于2022年第三季度银行业消费投诉情况的通报(以下简称通报)。通报指出,2022年第三季度,银保监会及其派出机构共接收并转送银行业消费春节过后,钢材价格会不会继续涨起来?高线大家新年好,首先,恭祝大家新年快乐,恭喜發財,财源滚滚。诚如我年前分析的一样,现阶段,由于政策的强制性指导,为保经济稳定,短期内,市场仍可保持一定的稳定性,甚至还能涨点。目前看瞭望金融改革化险应防未病治已病有效结合防范化解金融风险攻坚战以来,金融风险整体收敛总体可控高风险机构处置,要坚决避免通过不良资产假出表假注资等方式让机构假脱险当前,要防未病和治已病相结合,扎实推进中小金融机构改革化险文比亚迪卫冕2022年全球新能源汽车销冠,扣非净利润预计暴增11倍红星资本局1月30日消息,比亚迪(002594。SZ)晚间发布2022年度业绩预告,预计归属于上市公司股东的净利润160亿元170亿元,同比增长425。42458。26扣非净利润1史丹利云图控股松滋两大龙头企业开足建设马力视频史丹利云图控股两大龙头企业开足建设马力荆州新闻网消息新年伊始,奋楫扬帆正当时,在松滋市临港工业园,总投资额超百亿元的两大化工企业史丹利及云图控股,纷纷开足建设马力,大抓施工生产连接器行业分析报告量价齐升,看好行业国产替代机遇(报告出品方作者东莞证券,刘梦麟罗炜斌陈伟光)1。连接器是构成系统连接的基础元件,下游应用领域广泛连接器是构成完整系统连接所必须的基础元件。连接器(connector),即连接两个打造新苏南模式,新能源成支柱,江苏第五座万亿之城来势汹汹文虚渊玄1月28日,兔年首个工作日,常州市委市政府召开新能源之都建设推进大会,进一步强化新能源产业对于常州经济未来的重要性。大会出台常州市推进新能源之都建设政策措施,总投资折合人民老面孔成耀东挂帅,新一代中国奥运男足正式竖旗,无缘巴黎奥运是大概率事件?又一个四年,又一次争夺奥运男子足球的入场券。中国足协近日宣布,中国奥林匹克男子足球队将于2月7日至27日在上海集训,主教练是成耀东。这也意味着,新一代中国国奥队正式竖旗。只要存在一开新能源车回老家,我肠子都悔青了去年2月,中消协在春节消费维权舆情分析报告中点名高速充电难是典型案例。今年春运,这一难题再次成为新能源车车主头疼的事。开新能源车出行,电是个大问题。据每日经济新闻报道,已经两年没回
10月电脑装机配置怎么选,i512600KRTX3080显卡依然绝对主流全新的板U平台,最新的RTX4090显卡,扎堆到来!但是,跟买不起的我又有什么关系呢?老老实实趁着老平台显卡价格大跳水,攒台实用的高性能游戏主机,不香么?正好又新入手了一款机箱,融见证奇迹!1人能做出3A品质中世纪种田全面战争大作?内容来自GameLook图文来源一致近日,最新一期的Steam新品节正式开启,为全球玩家带来了数百款游戏Demo体验。其中,独立开发者SlavicMagic利用虚幻引擎4开发的新游腾讯新游戏不足半月就凉凉,大厂引进国外IP这条路不好走了?IP改编类型游戏一直是国内大厂不断深耕的类型,因为这类游戏角色剧情甚至是技能都已经有现成的模板了,只需要将之开发成产品就能够上线。并且,原作自带一批粉丝,上线之后能够快速收获用户。羊了个羊游戏一天能赚多少钱最近羊了个羊小游戏特别火,最重要的原因是它来了个反常,人家通关都是一关一关难度慢慢增加,而羊了个羊第二关就难度飙升,这就把那些爱较劲的人圈进去了。每次游戏必须要用道具如图没有人不用TES的s12摇摇欲坠,左手和阿水争相揽锅我们不能继续送了前导s12小组赛赛场进行过半,形式也逐渐明朗了没想到,被大家寄予厚望的C组爆冷。本以为TES能轻松出线,小组第一不在话下。谁知他们连续输给DRX和RGE战队,所谓最轻松的小组名不副科普ampamp39试管婴儿过程中存在哪些关键性影响因素?(下)其次,基因检测和冷冻解冻技术(一)基因检测更安全如果在移植前对胚胎进行基因测试,那么将胚胎生长到囊胚会有所帮助。当测试预测胚胎的染色体数量显示错误时,意味着这个胚胎几乎不能顺利活产荣耀中高端系列新机处理器曝光,新主摄和百瓦快充是亮点荣耀在中高端机市场中占有一席之地,失去了华为麒麟芯片的荣耀并没有因此止步不前,而是在今年的一季度实现了1500万台的出货量,拿下了第一的宝座。接下来的时间,荣耀有多款中高端机将会与中国汽车产销继续保持快速增长中新社北京10月11日电(记者闫晓虹)中国汽车工业协会11日发布2022年9月汽车工业产销情况9月,中国汽车产销继续保持快速增长,彰显传统销售旺季本色,当月产销分别达到267。2万在人类母乳中首次发现了微塑料颗粒,是否会对婴儿产生身体危害?我看到这样一篇文章,据说在母乳中发现了微塑料颗粒。我本身是一个哺乳期的妈妈,对于母乳类的报道,我是十分关注的。由意大利马尔凯理工大学科学家研究团队收集了34位健康产妇在分娩后一周提两个矮个子父母,确养育了一个1米八的男孩父母的身高也不一定会遗传孩子!我和老公都生于1954年,个子都长得矮小,一个1米64公分,一个1米53公分,结婚后,最耽心以后生的孩子也不高,用俩人的身高加起来计算,孩子也只能长到露营热带火野外烧烤!专业人士提醒不要在正风口点火北京日报客户端记者褚英硕支起帐篷和烧烤架,打开折叠桌椅露营不仅成为热门的休闲方式,也带火了户外烧烤。而秋季来临,风干物燥让明火给靠近树林和草丛的露营地带来了隐患。一些露营者由于缺少