好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

Java实现级联下拉结构的示例代码

前言

在开发过程中,会遇到很多的实体需要将查出的数据处理为下拉或者级联下拉的结构,提供给前端进行展示。

在数据库查出的结构中,可能是集合<实体类>的结构,也有可能是List<Map>的结构。

在下拉或者级联下拉的节点数据中,有时候还需要动态的携带其他的参数,已便于前端对某些数据的显示

如区域的级联下拉树中,需要携带经纬度的区域–在选择的时候在地图展示该区域

基于上面的业务场景,构建了下面的工具类,不当的地方请大家多多指教

注:在构建下拉树的时候,会存在父类id的判断,可能没有涵盖到你们的使用情况,自行修改添加

构建统一返回下拉结构

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

/**

  * Treeselect树结构实体类

  *

  * @author gongl

  */

@ApiModel ( "下拉树结构" )

public class TreeSelect implements Serializable {

     private static final long serialVersionUID = 1L;

 

     /**

      * 节点ID

      */

     @ApiModelProperty ( "节点id" )

     private String id;

 

     /**

      * 节点名称

      */

     @ApiModelProperty ( "节点名" )

     private String label;

 

     /**

      * 下拉节点中携带数据

      */

     @JsonInclude (JsonInclude.Include.NON_EMPTY)

     @ApiModelProperty ( "节点携带数据" )

     private Map<String, Object> dataMap;

 

 

     /**

      * 子节点

      */

     @JsonInclude (JsonInclude.Include.NON_EMPTY)

     @ApiModelProperty ( "子节点集合" )

     private List<TreeSelect> children;

 

 

     public TreeSelect() {

 

     }

 

 

     public String getId() {

         return id;

     }

 

     public void setId(String id) {

         this .id = id;

     }

 

     public String getLabel() {

         return label;

     }

 

     public void setLabel(String label) {

         this .label = label;

     }

 

     public List<TreeSelect> getChildren() {

         return children;

     }

 

     public void setChildren(List<TreeSelect> children) {

         this .children = children;

     }

 

     public Map<String, Object> getDataMap() {

         return dataMap;

     }

 

     public void setDataMap(Map<String, Object> dataMap) {

         this .dataMap = dataMap;

     }

构建集合<对象>转下拉树工具类

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

/**

  * 下拉和级联下拉通用生成工具类

  *

  * @Author gongl

  * @Create 2022-01-12

  */

public class TreeSelectUtils {

     private static final Logger log = LoggerFactory.getLogger(TreeSelectUtils. class );

     /**

      * 默认id名称

      */

     public static final String ID = "id" ;

     /**

      * 默认父类id名称

      */

     public static final String PARENT = "parentId" ;

 

     /**

      * 默认label名称

      */

     public static final String LABEL = "name" ;

 

 

     /**

      * 单层下拉结构

      *

      * @param collection 目标集合

      * @param id         节点编号字段

      * @param label      节点名字段

      * @param clazz      集合元素类型

      * @param args       需要携带的参数

      * @return 转换后的下拉结构 TreeSelect

      */

     public static <E> List<TreeSelect> singleTree(Collection<E> collection, String id, String label,

                                                   Class<?> clazz, String... args) {

         try {

             if (collection == null || collection.isEmpty()) {

                 return null ;

             }

             Field idField;

             try {

                 idField = clazz.getDeclaredField(id);

             } catch (NoSuchFieldException e1) {

                 idField = clazz.getSuperclass().getDeclaredField(id);

             }

             Field labelField;

             try {

                 labelField = clazz.getDeclaredField(label);

             } catch (NoSuchFieldException e1) {

                 labelField = clazz.getSuperclass().getDeclaredField(label);

             }

             idField.setAccessible( true );

             labelField.setAccessible( true );

             List<TreeSelect> list = new ArrayList<>();

             for (E e : collection) {

                 TreeSelect select = new TreeSelect();

                 select.setId(String.valueOf(idField.get(e)));

                 select.setLabel(String.valueOf(labelField.get(e)));

                 list.add(select);

                 dynamicData(select, e, clazz, args);

             }

             idField.setAccessible( false );

             labelField.setAccessible( false );

             return list;

         } catch (Exception e) {

             log.error( "单层下拉异常:" , e);

             e.printStackTrace();

             return null ;

         }

     }

 

     /**

      * 集合转树结构(默认树结构字段)

      *

      * @param collection 目标集合

      * @param clazz      集合元素类型

      * @param args       需要携带的参数

      * @return 转换后的树形结构 TreeSelect

      */

     public static <E> List<TreeSelect> toTree( @NotNull Collection<E> collection, @NotNull Class<?> clazz,

                                               String... args) {

         return toTree(collection, null , null , null , clazz, args);

     }

 

     /**

      * 集合转树结构(自定义名称字段)

      *

      * @param collection 目标集合

      * @param label      节点名字段

      * @param clazz      集合元素类型

      * @param args       需要携带的参数

      * @return 转换后的树形结构 TreeSelect

      */

     public static <E> List<TreeSelect> toTree( @NotNull Collection<E> collection, @NotEmpty String label,

                                               @NotNull Class<?> clazz, String... args) {

         return toTree(collection, null , null , label, clazz, args);

     }

 

     /**

      * 集合转树结构(默认父类id字段为parentId,其他自定义)

      *

      * @param collection 目标集合

      * @param id         节点编号字段

      * @param label      节点名字段

      * @param clazz      集合元素类型

      * @param args       需要携带的参数

      * @return 转换后的树形结构  TreeSelect

      */

     public static <E> List<TreeSelect> toTree( @NotNull Collection<E> collection, @NotEmpty String id, @NotEmpty String label,

                                               @NotNull Class<?> clazz, String... args) {

         return toTree(collection, id, null , label, clazz, args);

     }

 

     /**

      * 集合转树结构(自定义树结构的字段)

      *

      * @param collection 目标集合

      * @param id         节点编号字段

      * @param parent     父节点编号字段

      * @param label      节点名字段

      * @param clazz      集合元素类型

      * @param args       需要携带的参数

      * @return 转换后的树形结构  TreeSelect

      */

     public static <E> List<TreeSelect> toTree( @NotNull Collection<E> collection, String id, String parent, String label,

                                               @NotNull Class<?> clazz, String... args) {

         try {

             if (collection == null || collection.isEmpty()) {

                 return null ;

             }

             //可以默认名称

             if (StringUtils.isEmpty(id)) {

                 id = ID;

             }

             if (StringUtils.isEmpty(parent)) {

                 parent = PARENT;

             }

             if (StringUtils.isEmpty(label)) {

                 label = LABEL;

             }

             //是对象

             return collectionObj(collection, id, parent, label, clazz, args);

         } catch (Exception e) {

             log.error( "多层下拉树异常:" , e);

             return null ;

         }

     }

 

 

     /**

      * 集合对象的封装

      */

     private static <E> List<TreeSelect> collectionObj( @NotNull Collection<E> collection, String id, String parent, String label,

                                                      @NotNull Class<?> clazz, String... args) throws NoSuchFieldException, IllegalAccessException {

         // 初始化根节点集合

         List<TreeSelect> list = new ArrayList<>();

         // 获取 id 字段, 从当前对象或其父类

         Field idField;

         try {

             idField = clazz.getDeclaredField(id);

         } catch (NoSuchFieldException e1) {

             idField = clazz.getSuperclass().getDeclaredField(id);

         }

         // 获取 parentId 字段, 从当前对象或其父类

         Field parentField;

         try {

             parentField = clazz.getDeclaredField(parent);

         } catch (NoSuchFieldException e1) {

             parentField = clazz.getSuperclass().getDeclaredField(parent);

         }

         // 获取 label 字段, 从当前对象或其父类

         Field labelField;

         try {

             labelField = clazz.getDeclaredField(label);

         } catch (NoSuchFieldException e1) {

             labelField = clazz.getSuperclass().getDeclaredField(label);

         }

         idField.setAccessible( true );

         parentField.setAccessible( true );

         labelField.setAccessible( true );

         // 找出所有的根节点

         for (E e : collection) {

             Object parentId = parentField.get(e);

             if (isParentNode(parentId, idField, collection)) {

                 TreeSelect select = new TreeSelect();

                 select.setId(String.valueOf(idField.get(e)));

                 select.setLabel(String.valueOf(labelField.get(e)));

                 list.add(select);

                 dynamicData(select, e, clazz, args);

             }

         }

         // 依次添加子节点

         for (TreeSelect select : list) {

             addChild(select, collection, idField, parentField, labelField, clazz, args);

         }

         idField.setAccessible( false );

         parentField.setAccessible( false );

         labelField.setAccessible( false );

         return list;

     }

 

 

     /**

      * 添加跟随下拉的字段

      *

      * @param treeSelect 当前节点

      * @param e

      * @param clazz

      * @param args       需要跟随的字段

      * @throws IllegalAccessException

      * @throws NoSuchFieldException

      */

     private static <E> void dynamicData( @NotNull TreeSelect treeSelect, @NotNull Object e, @NotNull Class<E> clazz, String... args) throws IllegalAccessException, NoSuchFieldException {

         if (args.length > 0 ) {

             Map<String, Object> dataMap = new HashMap<>();

             for (String arg : args) {

                 Field field;

                 try {

                     field = clazz.getDeclaredField(arg);

                 } catch (NoSuchFieldException e1) {

                     field = clazz.getSuperclass().getDeclaredField(arg);

                 }

                 field.setAccessible( true );

                 dataMap.put(arg, field.get(e));

                 field.setAccessible( false );

             }

             treeSelect.setDataMap(dataMap);

         }

     }

 

 

     /**

      * 为目标节点添加孩子节点

      *

      * @param node        目标节点

      * @param collection  目标集合

      * @param idField     ID 字段

      * @param parentField 父节点字段

      * @param labelField  字节点字段

      */

     private static <E> void addChild( @NotNull TreeSelect node, @NotNull Collection<E> collection,

                                      @NotNull Field idField, @NotNull Field parentField, @NotNull Field labelField,

                                      @NotNull Class<?> clazz, String... args) throws IllegalAccessException, NoSuchFieldException {

         //父节点的id

         String id = node.getId();

         //子节点集合

         List<TreeSelect> children = new ArrayList<>();

         for (E e : collection) {

             String parentId = String.valueOf(parentField.get(e));

             if (id.equals(parentId)) {

                 // 将当前节点添加到目标节点的孩子节点

                 TreeSelect treeSelect = new TreeSelect();

                 treeSelect.setId(String.valueOf(idField.get(e)));

                 treeSelect.setLabel(String.valueOf(labelField.get(e)));

                 dynamicData(treeSelect, e, clazz, args);

                 children.add(treeSelect);

                 // 递归添加子节点

                 addChild(treeSelect, collection, idField, parentField, labelField, clazz, args);

             }

         }

         node.setChildren(children);

     }

 

     /**

      * 判断是否是根节点, 判断方式为:

      * 1、父节点编号为空或为 0, 则认为是根节点

      * 2、父节点在集合中不存在父节点

      *

      * @param parentId 父节点编号

      * @return 是否是根节点

      */

     private static <E> boolean isParentNode(Object parentId, Field idField, @NotNull Collection<E> collection) throws IllegalAccessException {

         if (parentId == null ) {

             return true ;

         } else if (parentId instanceof String && (StringUtils.isEmpty(String.valueOf(parentId)) || parentId.equals( "0" ))) {

             return true ;

         } else if (parentId instanceof Long && Long.valueOf( 0 ).equals(parentId)) {

             return true ;

         } else {

             for (E e : collection) {

                 Object o = idField.get(e);

                 if (Objects.equals(o, parentId)) {

                     return false ;

                 }

             }

             return true ;

         }

     }

}

构建List<Map>转下拉或下拉树的工具类

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

/**

  * 下拉和级联下拉通用生成工具类

  *

  * @Author gongl

  * @Create 2022-01-12

  */

public class MapToTreeSelectUtils {

     private static final Logger log = LoggerFactory.getLogger(MapToTreeSelectUtils. class );

     /**

      * 数据库默认父类id名称

      */

     public static final String DB_PARENT = "parent_id" ;

 

     /**

      * 集合转树结构(自定义树结构的字段)

      *

      * @param collection 目标集合

      * @param id         节点编号字段

      * @param parent     父节点编号字段

      * @param label      节点名字段

      * @param args       需要携带的参数

      * @return 转换后的树形结构  TreeSelect

      */

     public static List<TreeSelect> mapToTree(String id, String parent, String label,

                                              @NotNull List<Map<String, Object>> collection, String... args) {

         try {

             if (collection == null || collection.isEmpty()) {

                 return new ArrayList<>();

             }

             //可以默认名称

             if (StringUtils.isEmpty(id)) {

                 id = TreeSelectUtils.ID;

             }

             if (StringUtils.isEmpty(parent)) {

                 parent = DB_PARENT;

             }

             if (StringUtils.isEmpty(label)) {

                 label = TreeSelectUtils.LABEL;

             }

             return collectionMap(id, parent, label, collection, args);

         } catch (Exception e) {

             log.error( "多层下拉树异常:" , e);

             return null ;

         }

     }

 

     /**

      * 集合map的封裝

      */

     private static List<TreeSelect> collectionMap(String id, String parent, String label,

                                                   @NotNull List<Map<String, Object>> collection, String... args) throws IllegalAccessException, NoSuchFieldException {

         List<TreeSelect> list = new ArrayList<>();

         // 找出所有的根节点

         for (Map<String, Object> next : collection) {

             Object parentId = next.get(parent);

             if (isParentNodeMap(parentId, id, collection)) {

                 TreeSelect select = new TreeSelect();

                 select.setId(String.valueOf(next.get(id)));

                 select.setLabel(String.valueOf(next.get(label)));

                 list.add(select);

                 dynamicData(select, next, args);

             }

         }

         // 依次添加子节点

         for (TreeSelect select : list) {

             addChildMap(select, id, parent, label, collection, args);

         }

         return list;

     }

 

 

     /**

      * 添加跟随下拉的字段

      *

      * @param treeSelect 当前节点

      * @param e

      * @param args       需要跟随的字段

      * @throws IllegalAccessException

      * @throws NoSuchFieldException

      */

     private static void dynamicData( @NotNull TreeSelect treeSelect, @NotNull Map<String, Object> e, String... args) throws IllegalAccessException, NoSuchFieldException {

         if (args.length > 0 ) {

             Map<String, Object> dataMap = new HashMap<>();

             for (String arg : args) {

                 dataMap.put(arg, e.get(arg));

             }

             treeSelect.setDataMap(dataMap);

         }

     }

 

     /**

      * 为目标节点添加孩子节点

      *

      * @param node       目标节点

      * @param collection 目标集合

      * @param id         ID 字段

      * @param parent     父节点字段

      * @param label      字节点字段

      */

     private static void addChildMap( @NotNull TreeSelect node, String id, String parent, String label,

                                     @NotNull List<Map<String, Object>> collection,

                                     String... args) throws IllegalAccessException, NoSuchFieldException {

         //父节点的id

         String nodeId = node.getId();

         //子节点集合

         List<TreeSelect> children = new ArrayList<>();

         for (Map<String, Object> e : collection) {

             String parentId = String.valueOf(e.get(parent));

             if (nodeId.equals(parentId)) {

                 // 将当前节点添加到目标节点的孩子节点

                 TreeSelect treeSelect = new TreeSelect();

                 treeSelect.setId(String.valueOf(e.get(id)));

                 treeSelect.setLabel(String.valueOf(e.get(label)));

                 dynamicData(treeSelect, e, args);

                 children.add(treeSelect);

                 node.setChildren(children);

                 // 递归添加子节点

                 addChildMap(treeSelect, id, parent, label, collection, args);

             }

         }

     }

 

 

     /**

      * 判断是否是根节点, 判断方式为:

      * 1、父节点编号为空或为 0, 则认为是根节点

      * 2、父节点在集合中不存在父节点

      *

      * @param parentId 父节点编号

      * @return 是否是根节点

      */

     private static boolean isParentNodeMap(Object parentId, String id, @NotNull List<Map<String, Object>> collection) {

         if (parentId == null ) {

             return true ;

         } else if (parentId instanceof String && (StringUtils.isEmpty(String.valueOf(parentId)) || parentId.equals( "0" ))) {

             return true ;

         } else if (parentId instanceof Long && Long.valueOf( 0 ).equals(parentId)) {

             return true ;

         } else {

             for (Map<String, Object> e : collection) {

                 Object o = e.get(id);

                 if (Objects.equals(o, parentId)) {

                     return false ;

                 }

             }

             return true ;

         }

     }

}

到此这篇关于Java实现级联下拉结构的示例代码的文章就介绍到这了,更多相关Java级联下拉内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!

原文链接:https://blog.csdn.net/weixin_47914635/article/details/123551329

查看更多关于Java实现级联下拉结构的示例代码的详细内容...

  阅读:23次