Java把List集合转成树形结构

avatar
作者
猴君
阅读量:0

1. 实体类

<dependency>     <groupId>org.projectlombok</groupId>     <artifactId>lombok</artifactId>     <version>1.18.22</version> </dependency>
package com.utils;  import lombok.Data; import java.util.List;  /**  * @Description:  * @Author:   * @Date: 2021/12/16 9:35  */ @Data public class TestEntity {     private int id;     private String name;     private int parentId;          private List<TestEntity> children;  }

2. 方法一:使用Stream流

private static List<TestEntity> listToTree1(List<TestEntity> list) {     // 要点     // 通过Collectors.groupingBy(Address::getPid)方法对addresses按照Pid进行分组,也就是将pid相同的放在一起     Map<Integer, List<TestEntity>> parentMap = list.stream().collect(Collectors.groupingBy(TestEntity::getParentId));     list.forEach(item -> {         item.setChildren(parentMap.get(item.getId()));     });     // 过滤出根节点集合,根节点已经包含了孩子节点     List<TestEntity> newList = list.stream().filter(item -> item.getParentId() == 0).collect(Collectors.toList());     return newList; }

3. 方法二:使用fastjson

添加依赖

<dependency>     <groupId>com.alibaba</groupId>     <artifactId>fastjson</artifactId>     <version>1.2.73</version> </dependency>
/** * @param list          :要转成树的集合 * @param keyMark       :id * @param parentKeyMark :pid * @param childMark     :children * @return List:树集合 * @description :如TestEntity中有字段    int id,String name,int parentId,List<TestEntity> children字段 * keyMark、parentKeyMark、childMark就是    "id", "parentId", "children" */ public static List<TestEntity> listToTree2(List<TestEntity> list, String keyMark, String parentKeyMark, String childMark) {     JSONArray jsonArray = JSONArray.parseArray(JSONObject.toJSONString(list));     JSONArray jsonArrayTree = new JSONArray();     JSONObject hash = new JSONObject();     //将数组转为Object的形式,key为数组中的id     for (int i = 0; i < jsonArray.size(); i++) {         JSONObject json = (JSONObject) jsonArray.get(i);         hash.put(json.getString(keyMark), json);     }     //遍历结果集     for (int j = 0; j < jsonArray.size(); j++) {         //单条记录         JSONObject aVal = (JSONObject) jsonArray.get(j);         //在hash中取出key为单条记录中pid的值         if (null != aVal.get(parentKeyMark) && !"".equals(aVal.get(parentKeyMark))) {             JSONObject hashVP = (JSONObject) hash.get(aVal.get(parentKeyMark).toString());             //如果记录的pid存在,则说明它有父节点,将她添加到孩子节点的集合中             if (hashVP != null) {                 //检查是否有child属性                 if (hashVP.get(childMark) != null) {                     JSONArray ch = (JSONArray) hashVP.get(childMark);                     ch.add(aVal);                     hashVP.put(childMark, ch);                 } else {                     JSONArray ch = new JSONArray();                     ch.add(aVal);                     hashVP.put(childMark, ch);                 }             } else {                 jsonArrayTree.add(aVal);             }         } else {             jsonArrayTree.add(aVal);         }     }     return jsonArrayTree.toJavaList(TestEntity.class); }

4. 方法三:使用递归

/** * 使用递归方法建树 * * @param list 要转成树的集合 * @return List */ public static List<TestEntity> listToTree2(List<TestEntity> list) {     List<TestEntity> trees = new ArrayList<>();     for (TestEntity entity : list) {         int parentId = entity.getParentId();         if (parentId == 0) {             // 是父级             trees.add(findChildren(entity, list));         }     }     return trees; }  /** * 递归查找子节点 * * @param entity 对象 * @param list 子节点 * @return MenuTree */ private static TestEntity findChildren(TestEntity entity, List<TestEntity> list) {     for (TestEntity info : list) {         if (entity.getId() == info.getParentId()) {             if (entity.getChildren() == null) {                 entity.setChildren(new ArrayList<>());             }             entity.getChildren().add(findChildren(info, list));         }     }     return entity; }

5. 完整测试类

package list;  import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject;  import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors;  public class ListToTreeTest {     public static void main(String[] args) {         List<TestEntity> list = new ArrayList<>();          TestEntity testEntity1 = new TestEntity();         testEntity1.setId(1);         testEntity1.setName("张三");         testEntity1.setParentId(0);          TestEntity testEntity2 = new TestEntity();         testEntity2.setId(2);         testEntity2.setName("李四");         testEntity2.setParentId(0);          TestEntity testEntity3 = new TestEntity();         testEntity3.setId(3);         testEntity3.setName("张三儿子");         testEntity3.setParentId(1);          list.add(testEntity1);         list.add(testEntity2);         list.add(testEntity3);           List<TestEntity> result1 = listToTree1(list);         System.out.println(result1);  //        List<TestEntity> result2 = listToTree2(list, "id", "parentId", "children"); //        System.out.println(result2);  //        List<TestEntity> result3 = listToTree3(list); //        System.out.println(result3);      }      private static List<TestEntity> listToTree1(List<TestEntity> list) {         // 要点         // 通过Collectors.groupingBy(Address::getPid)方法对addresses按照Pid进行分组,也就是将pid相同的放在一起         Map<Integer, List<TestEntity>> parentMap = list.stream().collect(Collectors.groupingBy(TestEntity::getParentId));         list.forEach(item -> {             item.setChildren(parentMap.get(item.getId()));         });         // 过滤出根节点集合,根节点已经包含了孩子节点         List<TestEntity> newList = list.stream().filter(item -> item.getParentId() == 0).collect(Collectors.toList());         return newList;     }      /**      * @param list          :要转成树的集合      * @param keyMark       :id      * @param parentKeyMark :pid      * @param childMark     :children      * @return List:树集合      * @description :如TestEntity中有字段    int id,String name,int parentId,List<TestEntity> children字段      * keyMark、parentKeyMark、childMark就是    "id", "parentId", "children"      */     public static List<TestEntity> listToTree2(List<TestEntity> list, String keyMark, String parentKeyMark, String childMark) {         JSONArray jsonArray = JSONArray.parseArray(JSONObject.toJSONString(list));         JSONArray jsonArrayTree = new JSONArray();         JSONObject hash = new JSONObject();         //将数组转为Object的形式,key为数组中的id         for (int i = 0; i < jsonArray.size(); i++) {             JSONObject json = (JSONObject) jsonArray.get(i);             hash.put(json.getString(keyMark), json);         }         //遍历结果集         for (int j = 0; j < jsonArray.size(); j++) {             //单条记录             JSONObject aVal = (JSONObject) jsonArray.get(j);             //在hash中取出key为单条记录中pid的值             if (null != aVal.get(parentKeyMark) && !"".equals(aVal.get(parentKeyMark))) {                 JSONObject hashVP = (JSONObject) hash.get(aVal.get(parentKeyMark).toString());                 //如果记录的pid存在,则说明它有父节点,将她添加到孩子节点的集合中                 if (hashVP != null) {                     //检查是否有child属性                     if (hashVP.get(childMark) != null) {                         JSONArray ch = (JSONArray) hashVP.get(childMark);                         ch.add(aVal);                         hashVP.put(childMark, ch);                     } else {                         JSONArray ch = new JSONArray();                         ch.add(aVal);                         hashVP.put(childMark, ch);                     }                 } else {                     jsonArrayTree.add(aVal);                 }             } else {                 jsonArrayTree.add(aVal);             }         }         return jsonArrayTree.toJavaList(TestEntity.class);     }      /**      * 使用递归方法建树      *      * @param list 要转成树的集合      * @return List      */     public static List<TestEntity> listToTree3(List<TestEntity> list) {         List<TestEntity> trees = new ArrayList<>();         for (TestEntity entity : list) {             int parentId = entity.getParentId();             if (parentId == 0) {                 // 是父级                 trees.add(findChildren(entity, list));             }         }         return trees;     }      /**      * 递归查找子节点      *      * @param entity 对象      * @param list   子节点      * @return MenuTree      */     private static TestEntity findChildren(TestEntity entity, List<TestEntity> list) {         for (TestEntity info : list) {             if (entity.getId() == info.getParentId()) {                 if (entity.getChildren() == null) {                     entity.setChildren(new ArrayList<>());                 }                 entity.getChildren().add(findChildren(info, list));             }         }         return entity;     } }

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!