java 日常开发记录
前言
java 日常开发记录
java日常开发记录方便回查
一、java tree 树按父子关系平铺为集合(无限层级)
@Test
public void testSorted1() {
List<SortedEntity> list = new ArrayList<>();
list.add(new SortedEntity(2L, null));
list.add(new SortedEntity(1L, null));
list.add(new SortedEntity(3L, null));
list.add(new SortedEntity(11L, 3L));
list.add(new SortedEntity(10L, 3L));
list.add(new SortedEntity(7L, 2L));
list.add(new SortedEntity(8L, 2L));
list.add(new SortedEntity(9L, 2L));
list.add(new SortedEntity(4L, 1L));
list.add(new SortedEntity(5L, 1L));
list.add(new SortedEntity(6L, 1L));
list.add(new SortedEntity(12L, 4L));
list.add(new SortedEntity(13L, 4L));
list.add(new SortedEntity(14L, 11L));
list.add(new SortedEntity(15L, 11L));
list.add(new SortedEntity(16L, 10L));
list.add(new SortedEntity(17L, 13L));
list.add(new SortedEntity(18L, 13L));
list.add(new SortedEntity(19L, 18L));
list.add(new SortedEntity(20L, 19L));
Map<Long, SortedEntity> allMap = list.stream().collect(Collectors.toMap(SortedEntity::getId, Function.identity(), (s1, s2) -> s1));
list = list.stream().sorted((x, y) -> {
//定级
int xLevel = getLevel(allMap, x);
int yLevel = getLevel(allMap, y);
//不同级别
if(xLevel < yLevel){
SortedEntity xlevelObj = x;
SortedEntity yPlevelObj = getLevelObj(allMap, y, yLevel, xLevel);
//父子关系,子比父大,非父子按同级别处理
return xlevelObj == yPlevelObj ? -1 : sameLevelCompare(allMap,xlevelObj,yPlevelObj);
}else if(xLevel > yLevel){
SortedEntity ylevelObj = y;
SortedEntity xPlevelObj = getLevelObj(allMap, x, xLevel, yLevel);
//父子关系,子比父大,非父子按同级别处理
return ylevelObj == xPlevelObj ? 1 : sameLevelCompare(allMap,xPlevelObj,ylevelObj);
}
//同级别
return sameLevelCompare(allMap, x, y);
}).collect(Collectors.toList());
System.out.println(JSON.toJSONString(list, SerializerFeature.PrettyFormat));
}
private int sameLevelCompare(Map<Long, SortedEntity> allMap, SortedEntity x, SortedEntity y) {
SortedEntity xp = x, yp = y;
while (!Objects.equals(xp.getParentId(), yp.getParentId())){
//不同父,找同父
SortedEntity xse = allMap.get(xp.getParentId());
SortedEntity yse = allMap.get(yp.getParentId());
if(Objects.equals(xse,yse)){
//不同父id,但是都为空,即同为根节点
break;
}
if(xse != null){
xp = xse;
}
if(yse != null){
yp = yse;
}
}
//同父按子rank排序
return Comparator.comparing(SortedEntity::getRank).thenComparing(SortedEntity::getId)
.compare(xp, yp);
}
private SortedEntity getLevelObj(Map<Long, SortedEntity> allMap, SortedEntity c, int currLevel, int targetLevel) {
if(targetLevel > currLevel){
return null;
}
SortedEntity se = c;
for (int level = currLevel-1; level >= targetLevel && se != null && se.getParentId() != null; level--){
se = allMap.get(se.getParentId());
}
return se;
}
private int getLevel(Map<Long, SortedEntity> allMap, SortedEntity x) {
if(x.getLevel() != null){
return x.getLevel();
}
int level = 1;
SortedEntity se = x;
while (x.getParentId() != null && (se = allMap.get(se.getParentId())) != null){
level++;
}
x.setLevel(level);
return level;
}
@Data
public static class SortedEntity {
// 主键
private Long id;
// 父类id,顶级父类为null
private Long parentId;
// 排序字段
private Integer rank;
//层级表示,代码中会自动计算,这里启动缓存的作用,减少循环
private Integer level;
public SortedEntity(Long id, Long parentId) {
this.id = id;
this.parentId = parentId;
rank = RandomUtil.randomInt(1,5);
}
}