Stream list使用toMap转树形结构并保留插入顺序
public static List<InterfaceParamEntity> toTreeParams(List<InterfaceParamEntity> params) {
long rootId = InterfaceParamRootPid;
Map<Long, InterfaceParamEntity> map = params.stream().collect(toMap(InterfaceParamEntity::getId, k -> k));
if(map.values().stream().filter(node -> node.getIpaPid().equals(rootId))
.allMatch(node -> CollectionUtils.isEmpty(node.getChildren()))) {
map.values().stream()
.filter(node -> !(node.getIpaPid().equals(rootId)))
.forEach(node -> {
InterfaceParamEntity parentNode = map.get(node.getIpaPid());
if(parentNode != null){
if(parentNode.getChildren() == null)
parentNode.setChildren(new ArrayList<>());
parentNode.getChildren().add(node);
}
});
}
return map.values().stream()
.filter(node -> node.getIpaPid().equals(rootId))
.collect(toList());
}
核心代码 Stream Collectors.toMap 根据源码重写toMap方法 将HashMap 替换成LinkedHashMap既可
public static <T, K, U>
Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper) {
return toMap(keyMapper, valueMapper, throwingMerger(), HashMap::new);
}
private static <T> BinaryOperator<T> throwingMerger() {
return (u,v) -> { throw new IllegalStateException(String.format("Duplicate key %s", u)); };
}
stream.toMap 转换成有顺序的LinkedHashMap
public static <T, K, U> Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper) {
return Collectors.toMap(keyMapper, valueMapper,
(u,v) -> { throw new AppException(String.format("Duplicate key %s", u)); }, LinkedHashMap::new);
}
|