Tree Data Structure, JAVA8
-jdk8
-no dependency
Java로 일반적인 계층적 구조인 Tree 자료구조를 작성하였다.
TreeNode<Category> root = categories.stream().collect(toTreeNode());
)Category root = categories.stream().collect(toTree());
)
@Getter
class Category {
private int parentKey;
private int key;
private String name;
public Category(int parentKey, int key, String name) {
this.parentKey = parentKey;
this.key = key;
this.name = name;
}
}
// DB List
public List<Category> selectCategories(){
return Arrays.asList(
new Category(0, 1, "root"),
new Category(3, 6, "sub2-1"),
new Category(2, 4, "sub1-1"),
new Category(2, 5, "sub1-2"),
new Category(1, 2, "sub1"),
new Category(1, 3, "sub2"),
new Category(1, 7, "sub3")
);
}
List<Category> categories = selectCategories();
TreeNode<Category> root = categories.stream().collect(toTreeNode());
public Collector<Category,?,TreeNode<Category>> toTreeNode() {
return TreeNodeCollector<Category,Integer>.treeNode()
.id(Category::getId) //ID는??
.parentId(Category::getParentId) //Parent ID
.root(i->i.parentId==0) //Root는??
.toTree();
}
<결과>
> root
>> sub1
>>> sub1-1
>>> sub1-2
>> sub2
>>> sub2-1
>> sub3
assertThat(treeNode.get().getName(), is("root"));
assertThat(treeNode.getChildAt(0).getName(), is("sub1"));
assertThat(treeNode.getChildAt(1).getName(), is("sub2"));
assertThat(treeNode.getChildAt(2).getName(), is("sub3"));
assertThat(treeNode.getSubTreeAt(0).getChildAt(0).getName(), is("sub1-1"));
assertThat(treeNode.getSubTreeAt(0).getChildAt(1).getName(), is("sub1-2"));
assertThat(treeNode.getSubTreeAt(1).getChildAt(0).getName(), is("sub2-1"));
TreeSearchOption.depthFirst()
), 너비우선탐색(TreeSearchOption.breadthFirst()
) 제공한다. 또한 현재 노드에서 부모방향(TreeSearchOption.toParent()
)으로 탐색할수 있다Trees.searchFirst(root, A지점)
Trees.searchAll(root, 찾고자하는 predicate)
/**
* TreeNode Template
*
* root
* sub1
* sub1-1
* sub1-1-1
* sub1-1-2
* sub1-2
* sub1-2-1
* sub1-3
* sub2
* sub2-1
* sub2-2
* sub2-2-1
* sub2-2-2
* sub3
*/
TreeNode<String> node = Trees.searchFirst(treeNode, "sub1-1");
assertEquals(node.get(), "sub1-1");
List<TreeNode<String>> sub1s = Trees.searchAll(treeNode, o->o.get().startsWith("sub1-1"));
assertEquals(3, sub1s.size());
//sub1-1, sub1-1-1, sub1-1-2
Trees.pathFromRoot(A지점)
Trees.root(A지점)
Tree.leaves(A지점)
@Test
public void pathFromRoot() throws Exception {
TreeNode<String> node = Trees.searchFirst(treeNode, "sub1-1-2");
List<TreeNode<String>> parents = Trees.pathFromRoot(node);
List<String> parentContents = Trees.contents(parents);
assertEquals("root", parentContents.get(0));
assertEquals("sub1", parentContents.get(1));
assertEquals("sub1-1", parentContents.get(2));
assertEquals("sub1-1-2", parentContents.get(3));
}
@Test
public void root() throws Exception {
TreeNode<String> node = Trees.searchFirst(treeNode, "sub1-1-2");
TreeNode<String> root = Trees.root(node);
assertEquals(root, treeNode);
}
@Test
public void leaves() throws Exception {
List<TreeNode<String>> leaves = Trees.leaves(treeNode);
List<String> contents = Trees.contents(leaves);
assertTrue(contents.contains("sub1-1-1"));
assertTrue(contents.contains("sub1-1-2"));
assertTrue(contents.contains("sub1-2-1"));
assertTrue(contents.contains("sub1-3"));
assertTrue(contents.contains("sub2-1"));
assertTrue(contents.contains("sub2-2-1"));
assertTrue(contents.contains("sub2-2-2"));
assertTrue(contents.contains("sub3"));
}