一个List单位对象集合,主要字段是id parentId(本单位的父单位id,有多级) UnionCode(父code是2位数,子级每级递增2位)需要查找出这个集合中所存在的最上级的单位,(假如有父级单位A,子级单位为A1,A1的子级单位A2,集合中存在A1不存在A,那么最上级单位是A1,)以及如果存在中间有截断的情况,(如:集合中存在A,A2,需要将A2的parentId修改为A的id)
根据你的问题我第一反应用递归来做, 遍历集List合找到没有父单位的单位作为候选的最上级单位,然后递归地查找父级单位直到找到最顶层的单位
class Unit {
Integer id;
Integer parentId;
String unionCode;
}
public Unit findTopUnit(List<Unit> units) {
List<Unit> candidates = new ArrayList<>();
for (Unit unit : units) {
if (unit.parentId == null || !containsUnit(units, unit.parentId)) {
candidates.add(unit);
}
}
if (candidates.isEmpty()) {
return null;
}
Unit topUnit = candidates.get(0);
for (Unit candidate : candidates) {
if (isAncestor(units, candidate, topUnit)) {
topUnit = candidate;
}
}
return topUnit;
}
private boolean isAncestor(List<Unit> units, Unit ancestor, Unit unit) {
if (ancestor.id.equals(unit.id)) {
return true;
}
String parentUnionCode = getParentUnionCode(unit.unionCode);
Integer parentId = getParentId(units, parentUnionCode);
if (parentId == null) {
Unit parentUnit = new Unit();
parentUnit.id = -1;
parentUnit.parentId = null;
parentUnit.unionCode = parentUnionCode;
units.add(parentUnit);
parentId = parentUnit.id;
unit.parentId = parentId;
}
unit.parentId = parentId;
return isAncestor(units, ancestor, getUnitById(units, parentId));
}
private Integer getParentId(List<Unit> units, String unionCode) {
for (Unit unit : units) {
if (unit.unionCode.equals(unionCode)) {
return unit.id;
}
}
return null;
}
private String getParentUnionCode(String unionCode) {
int length = unionCode.length();
if (length <= 2) {
return null;
}
return unionCode.substring(0, length - 2);
}
private boolean containsUnit(List<Unit> units, Integer id) {
for (Unit unit : units) {
if (unit.id.equals(id)) {
return true;
}
}
return false;
}
private Unit getUnitById(List<Unit> units, Integer id) {
for (Unit unit : units) {
if (unit.id.equals(id)) {
return unit;
}
}
return null;
}
最终结果
/**
* 获取一级的单位节点
* @param units
* @return
*/
public List<UcBaseUnit> findTopUnit(List<UcBaseUnit> units) {
//找出units中不存在parentId的或者parentId=32个1的对象,可能为一级的单位
List<UcBaseUnit> candidates = new ArrayList<>();
Set<String> parentIds = units.stream().map(UcBaseUnit::getParentId).collect(Collectors.toSet());
for (UcBaseUnit unit : units) {
if (unit.getParentId().equals(BigdataConstant.GUID_ONE) || !parentIds.contains(unit.getId())) {
candidates.add(unit);
}
}
if (candidates.isEmpty()) {
return new ArrayList<>();
}
Map<String, UcBaseUnit> unionCodeMap = units.stream().collect(Collectors.toMap(UcBaseUnit::getUnionCode, Function.identity()));
List<UcBaseUnit> topUnits = new ArrayList<>();
for (UcBaseUnit candidate : candidates) {
//判断是否确为一级单位
if (isAncestor(candidate, unionCodeMap)) {
topUnits.add(candidate);
}else {
for (UcBaseUnit unit : units) {
if (unit.getId().equals(candidate.getId())) {
unit.setParentId(candidate.getParentId());
break;
}
}
}
}
return topUnits;
}
/**
* 判断是否为一级单位
* @param ancestor
* @param unionCodeMap
* @return
*/
private boolean isAncestor( UcBaseUnit ancestor, Map<String, UcBaseUnit> unionCodeMap) {
boolean result = false;
//获取本单位所有的上级unionCode
List<String> unionCodes = new ArrayList<>();
getParentUnionCodes(ancestor.getUnionCode(),unionCodes);
//所有上级unionCode 从大到小 越大说明层级越深
unionCodes = unionCodes.stream().sorted(Comparator.comparingInt(String::length).reversed()).collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(unionCodes)){
//判断当前单位的所有上级单位的unionCode是否存在
for (String code : unionCodes) {
UcBaseUnit ucBaseUnit = unionCodeMap.get(code);
if (Objects.isNull(ucBaseUnit)){
result = true;
}else {
result = false;
ancestor.setParentId(ucBaseUnit.getId());
}
}
}
return result;
}
private void getParentUnionCodes(String unionCode,List<String> unionCodes){
int length = unionCode.length();
String code = unionCode.substring(0, length - 2);
if (length>2) {
unionCodes.add(code);
getParentUnionCodes(code, unionCodes);
}
}