准备阶段
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 + '\'' +'}';}
}
- 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}