表结构
RecursionBean
@Getter
@Setter
@ToString
@JsonInclude ( JsonInclude. Include . NON_EMPTY)
public class RecursionBean < T > extends BaseVO {
private T id;
private T pid;
private List < ? extends RecursionBean < T > > children;
}
封装从服务器端返回的树形数据:RecursionItem
@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class RecursionItem < T > extends RecursionBean < T > {
private String name;
public RecursionItem ( T id, String name) {
super . setId ( id) ;
this . name = name;
}
public RecursionItem ( T id, String name, List < ? extends RecursionBean < T > > children) {
super . setId ( id) ;
this . name = name;
super . setChildren ( children) ;
}
}
工具类
public class RecursionBeanUtil {
private static < E , T extends RecursionBean < E > > List < T > getChildren ( T root, List < T > list) {
final List < T > res = new ArrayList < > ( ) ;
for ( T item : list) {
if ( Objects . equals ( item. getPid ( ) , root. getId ( ) ) ) {
item. setChildren ( getChildren ( item, list) ) ;
res. add ( item) ;
}
}
return res;
}
public static < E , T extends RecursionBean < E > > List < T > getRecursionList ( List < T > list) {
if ( CollectionUtil . isEmpty ( list) ) {
return list;
}
final List < E > allList = list. stream ( )
. map ( T :: getId )
. toList ( ) ;
final List < E > topList = list. stream ( )
. filter ( item -> item. getPid ( ) == null )
. map ( T :: getId )
. toList ( ) ;
final List < E > parentList = list. stream ( )
. map ( T :: getPid )
. filter ( itemPid -> ! topList. contains ( itemPid) )
. distinct ( )
. toList ( ) ;
final List < E > leafList = allList. stream ( )
. filter ( id -> ! topList. contains ( id) )
. filter ( id -> ! parentList. contains ( id) )
. toList ( ) ;
final List < T > res = new ArrayList < > ( ) ;
boolean topFlag = true ;
for ( T item : list) {
if ( item. getPid ( ) == null ) {
topFlag = false ;
item. setChildren ( getChildren ( item, list) ) ;
res. add ( item) ;
}
}
if ( ! topFlag) {
return res;
}
boolean parentFlag = true ;
for ( T item : list) {
if ( parentList. contains ( item. getPid ( ) ) && ! leafList. contains ( item. getId ( ) ) ) {
item. setChildren ( getChildren ( item, list) ) ;
parentFlag = false ;
res. add ( item) ;
}
}
if ( ! parentFlag) {
return res;
}
for ( T item : list) {
if ( leafList. contains ( item. getId ( ) ) ) {
item. setChildren ( getChildren ( item, list) ) ;
res. add ( item) ;
}
}
return res;
}
}