diff options
Diffstat (limited to 'BJC-Utils2/src/main/java/bjc/utils/funcdata/Tree.java')
| -rw-r--r-- | BJC-Utils2/src/main/java/bjc/utils/funcdata/Tree.java | 265 |
1 files changed, 135 insertions, 130 deletions
diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/Tree.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/Tree.java index cd43df7..b56ff48 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/Tree.java +++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/Tree.java @@ -21,7 +21,7 @@ public class Tree<ContainedType> implements ITree<ContainedType> { private boolean hasChildren; - private int childCount; + private int childCount = 0; /** * Create a new leaf node in a tree @@ -43,21 +43,15 @@ public class Tree<ContainedType> implements ITree<ContainedType> { * @param childrn * A list of children for this node */ - @SafeVarargs - public Tree(ContainedType leafToken, ITree<ContainedType>... childrn) { + public Tree(ContainedType leafToken, + IFunctionalList<ITree<ContainedType>> childrn) { data = leafToken; hasChildren = true; - childCount = 0; - - children = new FunctionalList<>(); - - for (ITree<ContainedType> child : childrn) { - children.add(child); + childCount = childrn.getSize(); - childCount++; - } + children = childrn; } /** @@ -68,15 +62,21 @@ public class Tree<ContainedType> implements ITree<ContainedType> { * @param childrn * A list of children for this node */ - public Tree(ContainedType leafToken, - IFunctionalList<ITree<ContainedType>> childrn) { + @SafeVarargs + public Tree(ContainedType leafToken, ITree<ContainedType>... childrn) { data = leafToken; hasChildren = true; - childCount = childrn.getSize(); + childCount = 0; - children = childrn; + children = new FunctionalList<>(); + + for (ITree<ContainedType> child : childrn) { + children.add(child); + + childCount++; + } } @Override @@ -93,28 +93,6 @@ public class Tree<ContainedType> implements ITree<ContainedType> { } @Override - public <TransformedType> TransformedType transformHead( - Function<ContainedType, TransformedType> transformer) { - return transformer.apply(data); - } - - @Override - public int getChildrenCount() { - return childCount; - } - - @Override - public <TransformedType> TransformedType transformChild(int childNo, - Function<ITree<ContainedType>, TransformedType> transformer) { - if (childNo < 0 || childNo > (childCount - 1)) { - throw new IllegalArgumentException( - "Child index #" + childNo + " is invalid"); - } - - return transformer.apply(children.getByIndex(childNo)); - } - - @Override public <NewType, ReturnedType> ReturnedType collapse( Function<ContainedType, NewType> leafTransform, Function<ContainedType, Function<IFunctionalList<NewType>, NewType>> nodeCollapser, @@ -124,23 +102,9 @@ public class Tree<ContainedType> implements ITree<ContainedType> { .apply(internalCollapse(leafTransform, nodeCollapser)); } - protected <NewType> NewType internalCollapse( - Function<ContainedType, NewType> leafTransform, - Function<ContainedType, Function<IFunctionalList<NewType>, NewType>> nodeCollapser) { - if (hasChildren) { - Function<IFunctionalList<NewType>, NewType> nodeTransformer = - nodeCollapser.apply(data); - - IFunctionalList<NewType> collapsedChildren = - children.map((child) -> { - return child.collapse(leafTransform, nodeCollapser, - (subTreeVal) -> subTreeVal); - }); - - return nodeTransformer.apply(collapsedChildren); - } - - return leafTransform.apply(data); + @Override + public void doForChildren(Consumer<ITree<ContainedType>> action) { + children.forEach(action); } @Override @@ -159,68 +123,44 @@ public class Tree<ContainedType> implements ITree<ContainedType> { } @Override - public void selectiveTransform(Predicate<ContainedType> nodePicker, - UnaryOperator<ContainedType> transformer) { - if (hasChildren) { - children.forEach((child) -> child - .selectiveTransform(nodePicker, transformer)); - } else { - data = transformer.apply(data); - } + public int getChildrenCount() { + return childCount; } - @Override - public <MappedType> ITree<MappedType> transformTree( - Function<ContainedType, MappedType> transformer) { + protected <NewType> NewType internalCollapse( + Function<ContainedType, NewType> leafTransform, + Function<ContainedType, Function<IFunctionalList<NewType>, NewType>> nodeCollapser) { if (hasChildren) { - IFunctionalList<ITree<MappedType>> transformedChildren = - children.map( - (child) -> child.transformTree(transformer)); + Function<IFunctionalList<NewType>, NewType> nodeTransformer = + nodeCollapser.apply(data); - return new Tree<>(transformer.apply(data), - transformedChildren); + IFunctionalList<NewType> collapsedChildren = + children.map((child) -> { + return child.collapse(leafTransform, nodeCollapser, + (subTreeVal) -> subTreeVal); + }); + + return nodeTransformer.apply(collapsedChildren); } - return new Tree<>(transformer.apply(data)); + return leafTransform.apply(data); } - @Override - public void traverse(TreeLinearizationMethod linearizationMethod, - Consumer<ContainedType> action) { - if (hasChildren) { - switch (linearizationMethod) { - case INORDER: - if (childCount != 2) { - throw new IllegalArgumentException( - "Can only do in-order traversal for binary trees."); - } - - children.getByIndex(0).traverse(linearizationMethod, - action); - - action.accept(data); - - children.getByIndex(1).traverse(linearizationMethod, - action); - break; - case POSTORDER: - children.forEach((child) -> child - .traverse(linearizationMethod, action)); - - action.accept(data); - break; - case PREORDER: - action.accept(data); + protected void internalToString(StringBuilder builder, int indentLevel, + boolean initial) { + if (!initial) { + StringUtils.indentNLevels(builder, indentLevel); + } - children.forEach((child) -> child - .traverse(linearizationMethod, action)); - break; - default: - break; + builder.append("Node: "); + builder.append(data == null ? "(null)" : data.toString()); + builder.append("\n"); - } - } else { - action.accept(data); + if (hasChildren) { + children.forEach((child) -> { + ((Tree<ContainedType>) child).internalToString(builder, + indentLevel + 2, false); + }); } } @@ -243,31 +183,13 @@ public class Tree<ContainedType> implements ITree<ContainedType> { } @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - - internalToString(builder, 1, true); - - builder.deleteCharAt(builder.length() - 1); - - return builder.toString(); - } - - protected void internalToString(StringBuilder builder, int indentLevel, - boolean initial) { - if (!initial) { - StringUtils.indentNLevels(builder, indentLevel); - } - - builder.append("Node: "); - builder.append(data == null ? "(null)" : data.toString()); - builder.append("\n"); - + public void selectiveTransform(Predicate<ContainedType> nodePicker, + UnaryOperator<ContainedType> transformer) { if (hasChildren) { - children.forEach((child) -> { - ((Tree<ContainedType>) child).internalToString(builder, - indentLevel + 2, false); - }); + children.forEach((child) -> child + .selectiveTransform(nodePicker, transformer)); + } else { + data = transformer.apply(data); } } @@ -312,4 +234,87 @@ public class Tree<ContainedType> implements ITree<ContainedType> { } } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + + internalToString(builder, 1, true); + + builder.deleteCharAt(builder.length() - 1); + + return builder.toString(); + } + + @Override + public <TransformedType> TransformedType transformChild(int childNo, + Function<ITree<ContainedType>, TransformedType> transformer) { + if (childNo < 0 || childNo > (childCount - 1)) { + throw new IllegalArgumentException( + "Child index #" + childNo + " is invalid"); + } + + return transformer.apply(children.getByIndex(childNo)); + } + + @Override + public <TransformedType> TransformedType transformHead( + Function<ContainedType, TransformedType> transformer) { + return transformer.apply(data); + } + + @Override + public <MappedType> ITree<MappedType> transformTree( + Function<ContainedType, MappedType> transformer) { + if (hasChildren) { + IFunctionalList<ITree<MappedType>> transformedChildren = + children.map( + (child) -> child.transformTree(transformer)); + + return new Tree<>(transformer.apply(data), + transformedChildren); + } + + return new Tree<>(transformer.apply(data)); + } + + @Override + public void traverse(TreeLinearizationMethod linearizationMethod, + Consumer<ContainedType> action) { + if (hasChildren) { + switch (linearizationMethod) { + case INORDER: + if (childCount != 2) { + throw new IllegalArgumentException( + "Can only do in-order traversal for binary trees."); + } + + children.getByIndex(0).traverse(linearizationMethod, + action); + + action.accept(data); + + children.getByIndex(1).traverse(linearizationMethod, + action); + break; + case POSTORDER: + children.forEach((child) -> child + .traverse(linearizationMethod, action)); + + action.accept(data); + break; + case PREORDER: + action.accept(data); + + children.forEach((child) -> child + .traverse(linearizationMethod, action)); + break; + default: + break; + + } + } else { + action.accept(data); + } + } } |
