1 表结构和数据
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for address
-- ----------------------------
DROP TABLE IF EXISTS `address`;
CREATE TABLE `address` (
`id` int NOT NULL AUTO_INCREMENT COMMENT 'ID',
`pid` int NULL DEFAULT NULL COMMENT '父id',
`name` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '名称',
`sort` int NULL DEFAULT NULL COMMENT '排序',
PRIMARY KEY (`id`) USING BTREE,
INDEX `pid`(`pid` ASC) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 40 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci COMMENT = '地区表' ROW_FORMAT = DYNAMIC;
-- ----------------------------
-- Records of address
-- ----------------------------
INSERT INTO `address` VALUES (2, 0, '湖北省', 2);
INSERT INTO `address` VALUES (3, 0, '辽宁省', 3);
INSERT INTO `address` VALUES (4, 1, '杭州市', 1);
INSERT INTO `address` VALUES (5, 1, '宁波市', 2);
INSERT INTO `address` VALUES (6, 1, '温州市', 3);
INSERT INTO `address` VALUES (7, 4, '上城区', 1);
INSERT INTO `address` VALUES (8, 4, '西湖区', 2);
INSERT INTO `address` VALUES (9, 4, '滨江区', 3);
INSERT INTO `address` VALUES (10, 5, '海曙区', 1);
INSERT INTO `address` VALUES (11, 5, '鄞州区', 2);
INSERT INTO `address` VALUES (12, 5, '江北区', 3);
INSERT INTO `address` VALUES (13, 6, '鹿城区', 1);
INSERT INTO `address` VALUES (14, 6, '瓯海区', 2);
INSERT INTO `address` VALUES (15, 6, '龙湾区', 3);
INSERT INTO `address` VALUES (16, 2, '武汉市', 1);
INSERT INTO `address` VALUES (17, 2, '宜昌市', 2);
INSERT INTO `address` VALUES (18, 2, '襄阳市', 3);
INSERT INTO `address` VALUES (19, 16, '武昌区', 1);
INSERT INTO `address` VALUES (20, 16, '洪山区', 2);
INSERT INTO `address` VALUES (21, 16, '汉阳区', 3);
INSERT INTO `address` VALUES (22, 17, '西陵区', 1);
INSERT INTO `address` VALUES (23, 17, '伍家岗区', 2);
INSERT INTO `address` VALUES (24, 17, '猇亭区', 3);
INSERT INTO `address` VALUES (25, 18, '襄城区', 1);
INSERT INTO `address` VALUES (26, 18, '樊城区', 2);
INSERT INTO `address` VALUES (27, 18, '高新技术产业开发区', 3);
INSERT INTO `address` VALUES (28, 3, '沈阳市', 1);
INSERT INTO `address` VALUES (29, 3, '大连市', 2);
INSERT INTO `address` VALUES (30, 3, '鞍山市', 3);
INSERT INTO `address` VALUES (31, 28, '和平区', 1);
INSERT INTO `address` VALUES (32, 28, '沈河区', 2);
INSERT INTO `address` VALUES (33, 28, '皇姑区', 3);
INSERT INTO `address` VALUES (34, 29, '中山区', 1);
INSERT INTO `address` VALUES (35, 29, '西岗区', 2);
INSERT INTO `address` VALUES (36, 29, '沙河口区', 3);
INSERT INTO `address` VALUES (37, 30, '铁东区', 1);
INSERT INTO `address` VALUES (38, 30, '铁西区', 2);
INSERT INTO `address` VALUES (39, 30, '立山区', 3);
SET FOREIGN_KEY_CHECKS = 1;
2 pojo类
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.List;
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName(value = "address")
public class Area implements Serializable {
/**
* ID
*/
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
/**
* 父id
*/
@TableField(value = "pid")
private Integer pid;
/**
* 名称
*/
@TableField(value = "`name`")
private String name;
@TableField(value = "sort")
private Integer sort;
@TableField(exist = false)
private List<Area> children;
private static final long serialVersionUID = 1L;
}
3 核心类
import cn.huawei.shu.pojo.Area;
import cn.huawei.shu.service.AddressService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* 省市县 stream流 生成树结构
*/
@RestController
@RequestMapping("/address")
public class AddressController {
@Autowired
private AddressService addressService;
@GetMapping("list")
public Object listAddress() {
//所有节点数据
List<Area> list = addressService.list();
//根节点数据
List<Area> rootNodes = list.stream().filter((Area ta) -> ta.getPid() == 0).collect(Collectors.toList());
//非 根节点数据
List<Area> otherNodes = list.stream().filter((Area ta) -> ta.getPid() != 0).collect(Collectors.toList());
//根节点设置 childNode 属性
rootNodes.forEach(
xx-> setNodeChilds(xx, otherNodes)
);
return rootNodes;
}
/**
* 设置节点的childNode,并返回
* @param area
* @param otherNodes 非 根节点数据
* @return
*/
private static Area setNodeChilds(Area area, List<Area> otherNodes) {
//过滤出子节点的数据
Stream<Area> childNodes_temp = otherNodes.stream().filter(aa -> {
return aa.getPid() == area.getId();
});
//排序
Stream<Area> childNodes_temp_sort = childNodes_temp.sorted(Comparator.comparingInt(Area::getSort));
List<Area> childNodes = Optional.ofNullable(childNodes_temp_sort.collect(Collectors.toList())).orElse(new ArrayList<>());
//设置子节点属性
area.setChildren(childNodes);
//子节点再判断
if(!childNodes.isEmpty()) {
childNodes.stream().forEach(area_t -> setNodeChilds(area_t, otherNodes));
}
return area;
}
}