forked from plusone/plusone-commons
修改 API,使 TreeBuilder 实例可以复用。
parent
5cee71a342
commit
5d0af2dad5
7
pom.xml
7
pom.xml
|
@ -81,6 +81,13 @@
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.code.gson</groupId>
|
||||||
|
<artifactId>gson</artifactId>
|
||||||
|
<version>2.10.1</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|
|
@ -11,32 +11,29 @@ import java.util.stream.Collectors;
|
||||||
import xyz.zhouxy.plusone.commons.collection.CollectionTools;
|
import xyz.zhouxy.plusone.commons.collection.CollectionTools;
|
||||||
|
|
||||||
public class TreeBuilder<T, TSubTree extends T, TIdentity> {
|
public class TreeBuilder<T, TSubTree extends T, TIdentity> {
|
||||||
private final Collection<T> nodes;
|
|
||||||
private final Function<T, TIdentity> identityGetter;
|
private final Function<T, TIdentity> identityGetter;
|
||||||
private final Function<T, Optional<TIdentity>> parentIdentityGetter;
|
private final Function<T, Optional<TIdentity>> parentIdentityGetter;
|
||||||
private final BiConsumer<TSubTree, T> addChildrenMethod;
|
private final BiConsumer<TSubTree, T> addChildMethod;
|
||||||
|
|
||||||
public TreeBuilder(Collection<T> nodes, Function<T, TIdentity> identityGetter,
|
public TreeBuilder(Function<T, TIdentity> identityGetter, Function<T, Optional<TIdentity>> parentIdentityGetter,
|
||||||
Function<T, Optional<TIdentity>> parentIdentityGetter, BiConsumer<TSubTree, T> addChildren) {
|
BiConsumer<TSubTree, T> addChild) {
|
||||||
this.nodes = nodes;
|
|
||||||
this.identityGetter = identityGetter;
|
this.identityGetter = identityGetter;
|
||||||
this.parentIdentityGetter = parentIdentityGetter;
|
this.parentIdentityGetter = parentIdentityGetter;
|
||||||
this.addChildrenMethod = addChildren;
|
this.addChildMethod = addChild;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<T> buildTree() {
|
public List<T> buildTree(Collection<T> nodes) {
|
||||||
Map<TIdentity, T> identityNodeMap = CollectionTools.toHashMap(nodes, identityGetter);
|
Map<TIdentity, T> identityNodeMap = CollectionTools.toHashMap(nodes, identityGetter);
|
||||||
List<T> result = this.nodes.stream()
|
List<T> result = nodes.stream()
|
||||||
.filter(node -> !this.parentIdentityGetter.apply(node).isPresent())
|
.filter(node -> !this.parentIdentityGetter.apply(node).isPresent())
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
for (T node : this.nodes) {
|
nodes.forEach(node -> parentIdentityGetter.apply(node).ifPresent(parentIdentity -> {
|
||||||
Optional<TIdentity> parentIdentity = parentIdentityGetter.apply(node);
|
if (identityNodeMap.containsKey(parentIdentity)) {
|
||||||
if (parentIdentity.isPresent() && identityNodeMap.containsKey(parentIdentity.get())) {
|
@SuppressWarnings("unchecked")
|
||||||
@SuppressWarnings("all")
|
TSubTree parentNode = (TSubTree) identityNodeMap.get(parentIdentity);
|
||||||
TSubTree parentNode = (TSubTree) identityNodeMap.get(parentIdentity.get());
|
addChildMethod.accept(parentNode, node);
|
||||||
addChildrenMethod.accept(parentNode, node);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,12 +8,17 @@ import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
|
|
||||||
class TreeBuilderTests {
|
class TreeBuilderTests {
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(TreeBuilderTests.class);
|
private static final Logger log = LoggerFactory.getLogger(TreeBuilderTests.class);
|
||||||
|
private final TreeBuilder<Menu, MenuList, String> treeBuilder = new TreeBuilder<>(
|
||||||
|
Menu::getMenuCode,
|
||||||
|
Menu::getParentMenuCode,
|
||||||
|
MenuList::addChild);
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testBuildTree() {
|
void testBuildTree() {
|
||||||
|
@ -31,13 +36,10 @@ class TreeBuilderTests {
|
||||||
MenuItem.of("C", "C2", "二级菜单C2", "/c/c2"),
|
MenuItem.of("C", "C2", "二级菜单C2", "/c/c2"),
|
||||||
MenuItem.of("C", "C3", "二级菜单C3", "/c/c3")
|
MenuItem.of("C", "C3", "二级菜单C3", "/c/c3")
|
||||||
);
|
);
|
||||||
List<Menu> menuTree = new TreeBuilder<>(
|
|
||||||
menus,
|
List<Menu> menuTree = treeBuilder.buildTree(menus);
|
||||||
Menu::getMenuCode,
|
log.info("menuTree: {}", new Gson().toJson(menuTree));
|
||||||
Menu::getParentMenuCode,
|
|
||||||
MenuList::addChild)
|
|
||||||
.buildTree();
|
|
||||||
log.info("menuTree: {}", menuTree);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue