当前位置: 首页 > news >正文

Java 开发 - 扁平化数据转换成树形结构数据(递归查找 + 移除节点、Map + 一次遍历)

准备阶段

1、准备实体类
  1. Food.java
public class Food {private int id;private int parentId;private String name;public Food() {}public Food(int id, int parentId, String name) {this.id = id;this.parentId = parentId;this.name = name;}public int getId() {return id;}public void setId(int id) {this.id = id;}public int getParentId() {return parentId;}public void setParentId(int parentId) {this.parentId = parentId;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "Food{" +"id=" + id +", parentId=" + parentId +", name='" + name + '\'' +'}';}
}
  1. FoodItem.java
public class FoodItem {private int id;private String name;private int level;private List<FoodItem> children;public FoodItem() {}public FoodItem(int id, String name, int level, List<FoodItem> children) {this.id = id;this.name = name;this.level = level;this.children = children;}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getLevel() {return level;}public void setLevel(int level) {this.level = level;}public List<FoodItem> getChildren() {return children;}public void setChildren(List<FoodItem> children) {this.children = children;}@Overridepublic String toString() {return "FoodItem{" +"id=" + id +", name='" + name + '\'' +", level=" + level +'}';}
}
2、准备数据
private static List<Food> getData() {List<Food> foods = Arrays.asList(new Food(1, 0, "水果"),new Food(2, 0, "蔬菜"),new Food(3, 0, "肉类"),// 水果的子类(二级分类)new Food(4, 1, "苹果"),new Food(5, 1, "香蕉"),new Food(6, 1, "橙子"),// 蔬菜的子类(二级分类)new Food(7, 2, "胡萝卜"),new Food(8, 2, "菠菜"),new Food(9, 2, "西红柿"),// 肉类的子类(二级分类)new Food(10, 3, "猪肉"),new Food(11, 3, "牛肉"),new Food(12, 3, "鸡肉"),// 苹果的子类(三级分类)new Food(13, 4, "红富士"),new Food(14, 4, "青苹果"),// 牛肉的子类(三级分类)new Food(15, 11, "牛腩"),new Food(16, 11, "牛排"));// 打乱列表顺序Collections.shuffle(foods);return foods;
}

方式 1:递归查找 + 移除节点

private static void test() {List<Food> foods = getData();for (Food food : foods) {System.out.println(food);}System.out.println("====================================================================================================");List<FoodItem> foodItems = new ArrayList<>();for (Food food : foods) {foodItems.add(new FoodItem(food.getId(), food.getName(), 0, null));}for (Food food : foods) {if (food.getParentId() == 0) {continue;}FoodItem parent = findParent(foodItems, food.getParentId());if (parent == null) {continue;}FoodItem self = findSelf(foodItems, food.getId());if (parent.getChildren() == null) {parent.setChildren(new ArrayList<>());}parent.getChildren().add(self);foodItems.remove(self);}setLevel(foodItems, 1);sortById(foodItems);printTree(foodItems);
}private static FoodItem findParent(List<FoodItem> foodItems, int parentId) {for (FoodItem foodItem : foodItems) {if (foodItem.getId() == parentId) {return foodItem;}if (foodItem.getChildren() != null) {FoodItem parent = findParent(foodItem.getChildren(), parentId);if (parent != null) {return parent;}}}return null;
}private static FoodItem findSelf(List<FoodItem> foodItems, int id) {for (FoodItem foodItem : foodItems) {if (foodItem.getId() == id) {return foodItem;}}return null;
}private static void setLevel(List<FoodItem> foodItems, int level) {for (FoodItem foodItem : foodItems) {foodItem.setLevel(level);if (foodItem.getChildren() != null) {setLevel(foodItem.getChildren(), level + 1);}}
}private static void sortById(List<FoodItem> foodItems) {Collections.sort(foodItems, Comparator.comparingInt(FoodItem::getId));for (FoodItem foodItem : foodItems) {if (foodItem.getChildren() != null) {sortById(foodItem.getChildren());}}
}private static void printTree(List<FoodItem> foodItems) {for (FoodItem foodItem : foodItems) {int level = foodItem.getLevel();if (level > 1) {System.out.println("-----".repeat(level - 1) + " " + foodItem);} else {System.out.println(foodItem);}if (foodItem.getChildren() != null) {printTree(foodItem.getChildren());}}
}
  • 输出结果
Food{id=4, parentId=1, name='苹果'}
Food{id=6, parentId=1, name='橙子'}
Food{id=1, parentId=0, name='水果'}
Food{id=14, parentId=4, name='青苹果'}
Food{id=8, parentId=2, name='菠菜'}
Food{id=9, parentId=2, name='西红柿'}
Food{id=5, parentId=1, name='香蕉'}
Food{id=13, parentId=4, name='红富士'}
Food{id=11, parentId=3, name='牛肉'}
Food{id=10, parentId=3, name='猪肉'}
Food{id=7, parentId=2, name='胡萝卜'}
Food{id=12, parentId=3, name='鸡肉'}
Food{id=16, parentId=11, name='牛排'}
Food{id=3, parentId=0, name='肉类'}
Food{id=2, parentId=0, name='蔬菜'}
Food{id=15, parentId=11, name='牛腩'}
====================================================================================================
FoodItem{id=1, name='水果', level=1}
----- FoodItem{id=4, name='苹果', level=2}
---------- FoodItem{id=13, name='红富士', level=3}
---------- FoodItem{id=14, name='青苹果', level=3}
----- FoodItem{id=5, name='香蕉', level=2}
----- FoodItem{id=6, name='橙子', level=2}
FoodItem{id=2, name='蔬菜', level=1}
----- FoodItem{id=7, name='胡萝卜', level=2}
----- FoodItem{id=8, name='菠菜', level=2}
----- FoodItem{id=9, name='西红柿', level=2}
FoodItem{id=3, name='肉类', level=1}
----- FoodItem{id=10, name='猪肉', level=2}
----- FoodItem{id=11, name='牛肉', level=2}
---------- FoodItem{id=15, name='牛腩', level=3}
---------- FoodItem{id=16, name='牛排', level=3}
----- FoodItem{id=12, name='鸡肉', level=2}

方式 2:Map + 一次遍历(推荐)

private static void test() {List<Food> foods = Arrays.asList(new Food(1, 0, "水果"),new Food(2, 0, "蔬菜"),new Food(3, 0, "肉类"),// 水果的子类(二级分类)new Food(4, 1, "苹果"),new Food(5, 1, "香蕉"),new Food(6, 1, "橙子"),// 蔬菜的子类(二级分类)new Food(7, 2, "胡萝卜"),new Food(8, 2, "菠菜"),new Food(9, 2, "西红柿"),// 肉类的子类(二级分类)new Food(10, 3, "猪肉"),new Food(11, 3, "牛肉"),new Food(12, 3, "鸡肉"),// 苹果的子类(三级分类)new Food(13, 4, "红富士"),new Food(14, 4, "青苹果"),// 牛肉的子类(三级分类)new Food(15, 11, "牛腩"),new Food(16, 11, "牛排"));// 打乱列表顺序Collections.shuffle(foods);for (Food food : foods) {System.out.println(food);}System.out.println("====================================================================================================");Map<Integer, FoodItem> foodItemMap = new HashMap<>();for (Food food : foods) {foodItemMap.put(food.getId(), new FoodItem(food.getId(), food.getName(), 0, null));}List<FoodItem> foodItems = new ArrayList<>();for (Food food : foods) {if (food.getParentId() == 0) {FoodItem foodItem = foodItemMap.get(food.getId());foodItems.add(foodItem);continue;}FoodItem parent = foodItemMap.get(food.getParentId());if (parent == null) {FoodItem foodItem = foodItemMap.get(food.getId());foodItems.add(foodItem);continue;}FoodItem foodItem = foodItemMap.get(food.getId());if (parent.getChildren() == null) {parent.setChildren(new ArrayList<>());}parent.getChildren().add(foodItem);}setLevel(foodItems, 1);sortById(foodItems);printTree(foodItems);
}private static void setLevel(List<FoodItem> foodItems, int level) {for (FoodItem foodItem : foodItems) {foodItem.setLevel(level);if (foodItem.getChildren() != null) {setLevel(foodItem.getChildren(), level + 1);}}
}private static void sortById(List<FoodItem> foodItems) {Collections.sort(foodItems, Comparator.comparingInt(FoodItem::getId));for (FoodItem foodItem : foodItems) {if (foodItem.getChildren() != null) {sortById(foodItem.getChildren());}}
}private static void printTree(List<FoodItem> foodItems) {for (FoodItem foodItem : foodItems) {int level = foodItem.getLevel();if (level > 1) {System.out.println("-----".repeat(level - 1) + " " + foodItem);} else {System.out.println(foodItem);}if (foodItem.getChildren() != null) {printTree(foodItem.getChildren());}}
}
  • 输出结果
Food{id=15, parentId=11, name='牛腩'}
Food{id=3, parentId=0, name='肉类'}
Food{id=16, parentId=11, name='牛排'}
Food{id=8, parentId=2, name='菠菜'}
Food{id=4, parentId=1, name='苹果'}
Food{id=11, parentId=3, name='牛肉'}
Food{id=12, parentId=3, name='鸡肉'}
Food{id=10, parentId=3, name='猪肉'}
Food{id=13, parentId=4, name='红富士'}
Food{id=6, parentId=1, name='橙子'}
Food{id=1, parentId=0, name='水果'}
Food{id=14, parentId=4, name='青苹果'}
Food{id=2, parentId=0, name='蔬菜'}
Food{id=5, parentId=1, name='香蕉'}
Food{id=9, parentId=2, name='西红柿'}
Food{id=7, parentId=2, name='胡萝卜'}
====================================================================================================
FoodItem{id=1, name='水果', level=1}
----- FoodItem{id=4, name='苹果', level=2}
---------- FoodItem{id=13, name='红富士', level=3}
---------- FoodItem{id=14, name='青苹果', level=3}
----- FoodItem{id=5, name='香蕉', level=2}
----- FoodItem{id=6, name='橙子', level=2}
FoodItem{id=2, name='蔬菜', level=1}
----- FoodItem{id=7, name='胡萝卜', level=2}
----- FoodItem{id=8, name='菠菜', level=2}
----- FoodItem{id=9, name='西红柿', level=2}
FoodItem{id=3, name='肉类', level=1}
----- FoodItem{id=10, name='猪肉', level=2}
----- FoodItem{id=11, name='牛肉', level=2}
---------- FoodItem{id=15, name='牛腩', level=3}
---------- FoodItem{id=16, name='牛排', level=3}
----- FoodItem{id=12, name='鸡肉', level=2}
http://www.dtcms.com/a/525325.html

相关文章:

  • 探寻企业数字化转型“底座”:技术基石与核心支撑
  • 做网站视频教学最简单的出入库管理软件
  • [MySQL]表——改变数据
  • 第十一篇《IPv4的救星:初识IPv6的地址格式与优势》
  • 好的网站推荐住房和城乡建设部网站施工员证
  • C++开发之责任链模式
  • JVM面试(内存结构,垃圾回收,类载机制)
  • 并发编程案例分析——高性能限流器Guava RateLimiter(四十六)
  • 灵巧手——faive_gym
  • 亚马逊电子配件类目流量瓶颈突破:DeepBI智能优化策略助力流量增长
  • 桂市做网站的朋友自建电商网站有哪些
  • autoware源码编译
  • react nextjs 项目部署
  • 怎样建设网站 需要哪些条件免费的免抠图素材网站
  • FPGA学习笔记——用Vitis IDE生成工程(串口发送)
  • 烟台 o2o平台带动做网站行业平潭综合实验区交通与建设网站
  • GaussianShader
  • 昆山企业做网站好用的网站系统
  • javaScript事件委托
  • 广州营销型网站建设哪家好公司域名怎么起
  • 28.C++的IO流
  • 车载基础软件——基础软件验证平台典型案例(通信相关)
  • 【FPGA】设计流程——板级验证
  • 1Panel-1Panel中openresty网站目录更改为宿主机共享目录
  • 分支和循环语句
  • 自己做网站买株洲平台公司有几家
  • 2.2softmax回归
  • EtherCAT转PROFINET网关在饲料厂自动化系统整合中的关键作用
  • 公司网站建设泉州福田住房和建设局官网
  • 2018建设网站企业网站页脚信息