I have this list of paths:
private static final List<String> paths = Arrays.asList(
"assets/css/custom.css",
"assets/css/default.css",
"assets/js/main.js",
"assets/js/old/main-old.js",
"fonts/poppins.woff",
"favicon.ico",
"index.html"
);
That I need to create a searchable tree, like this:
and here's what I have now:
public void testCreateTree() {
Node root = new Node("ROOT", null, Node.NODE_TYPE.ROOT);
paths.forEach(path -> {
final Node[] currentNode = {root};
if(!path.contains("/")) { // root files
currentNode[0].addChild(new Node(path, currentNode[0], Node.NODE_TYPE.FILE));
} else {
String folders = DirectoryRegex.matchFolders(path); // e.g. matches/returns "root/"
String fileName = DirectoryRegex.matchFile(path); // e.g. matches/returns index.html
String[] folderArrays = folders.split("/");
Arrays.asList(folderArrays).forEach(folder -> {
Node node = new Node("ROOT", null, Node.NODE_TYPE.ROOT);
node.setNodeName(folder);
node.setNodeType(Node.NODE_TYPE.FOLDER);
node.setParent(currentNode[0]);
// check if child exists
Node existingNode = currentNode[0].getChild(folder, Node.NODE_TYPE.FOLDER);
if(existingNode == null) {
existingNode = node;
currentNode[0].addChild(node);
}
currentNode[0] = existingNode;
});
currentNode[0].addChild(new Node(fileName, currentNode[0], Node.NODE_TYPE.FILE));
}
});
String print = root.printNodeJSON().toString();
Console.log(print);
}
The Node.java class is this:
public class Node {
public NODE_TYPE getNodeType() {
return nodeType;
}
public void setNodeType(NODE_TYPE nodeType) {
this.nodeType = nodeType;
}
public Node getParent() {
return parent;
}
public void setParent(Node parent) {
this.parent = parent;
}
public List<Node> getChildren() {
if(children == null) {
children = new LinkedList<>();
}
return children;
}
public void setChildren(List<Node> children) {
this.children = children;
}
public void addChild(Node child) {
getChildren().add(child);
}
public Node getChild(String nodeName, NODE_TYPE nodeType) {
final Node[] child = {null};
getChildren().forEach(node -> {
if(node.getNodeName().equals(nodeName) && node.getNodeType().equals(nodeType)) {
child[0] = node;
}
});
return child[0];
}
public String getNodeName() {
return nodeName;
}
public void setNodeName(String nodeName) {
this.nodeName = nodeName;
}
private Node() {}
public Node(String nodeName, Node parent, NODE_TYPE nodeType) {
setNodeName(nodeName);
setNodeType(nodeType);
setParent(parent);
}
public enum NODE_TYPE { FILE, FOLDER, ROOT }
private NODE_TYPE nodeType;
private Node parent;
private List<Node> children;
private String nodeName;
public String printNode() {
final String[] s = {"["};
s[0] = s[0] + "Node name: " + nodeName + ",";
if(nodeType != null) {
s[0] = s[0] + "Node type: " + nodeType.toString() + ",";
}
if(getParent() != null) {
s[0] = s[0] + "Node Parent: [ name = " + getParent().getNodeName() + ", type = " + getParent().getNodeType() + " ]";
}
s[0] = s[0] + "Node children: [";
getChildren().forEach(child -> {
s[0] = "[" + s[0] + child.printNode() + "]";
});
s[0] = s[0] + "]";
s[0] = s[0] + "]";
return s[0];
}
public JSONObject printNodeJSON() {
JSONObject jsonObject = new JSONObject();
jsonObject.put("nodeName", nodeName);
jsonObject.put("nodeType", nodeType != null ? nodeType.toString() : null);
jsonObject.put("parent", getParent() != null ? getParent().printNodeJSONWithoutChildren() : null);
JSONArray children = new JSONArray();
getChildren().forEach(child -> {
children.put(child.printNodeJSON());
});
jsonObject.put("children", children);
return jsonObject;
}
public JSONObject printNodeJSONWithoutChildren() {
JSONObject jsonObject = new JSONObject();
jsonObject.put("nodeName", nodeName);
jsonObject.put("nodeType", nodeType != null ? nodeType.toString() : null);
jsonObject.put("parent", getParent() != null ? getParent().printNodeJSONWithoutChildren() : null);
// JSONArray children = new JSONArray();
// getChildren().forEach(child -> {
// children.put(child.printNodeJSON());
// });
// jsonObject.put("children", children);
return jsonObject;
}
}
The code works fine but I want to know the most efficient way to do this.
Related
I'm looking for minimumlistPerValueOld working translate to minimumlistPerValueNew in the method getOptimizedTreeNodeResample(TreeNodeResample in, List<Integer> listSampleRateFinal)
/*I need to find the list that by adding it to the nested list,
the minimum number of operations required*/
private static TreeNodeResample getOptimizedTreeNodeResample(TreeNodeResample in, List<Integer> listSampleRateFinal) {
TreeNodeResample out = new TreeNodeResample(null);
listSampleRateFinal.forEach(sampleRateFinal -> {
List<List<NodeResample>> nestedListPerValue = getFilteredNestedListsValue(in, sampleRateFinal);
Long lastMinimum = Long.MAX_VALUE;
List<NodeResample> minimumlistPerValue = null;
for (List<NodeResample> listPerValue : nestedListPerValue) {
Long accumulator = addCalc(out.getNestedListsValue(), listPerValue)
.stream()
.map(nodeResample -> (long) nodeResample.getNumResampleOperations())
.mapToLong(Long::longValue).sum();
if (accumulator < lastMinimum) {
lastMinimum = accumulator;
minimumlistPerValue = listPerValue;
}
}
out.addListValue(minimumlistPerValue);
});
return out;
}
I believe I need to map listPerValue, as you can see listPerValue is the type List<NodeResample>
listPerValue -> {
TreeNodeResample temp = new TreeNodeResample(null);
temp.setNestedListsValue(out.getNestedListsValue());
temp.addListValue(listPerValue);
return temp.getListNodes();// return List<TreeNodeResample> type
}
Or map (to the same object type)
listPerValue -> {
TreeNodeResample temp = new TreeNodeResample(null);
temp.setNestedListsValue(out.getNestedListsValue());
temp.addListValue(listPerValue);
List<NodeResample> childsValues = temp.getListNodes()
.stream()
.map(node -> node.getValue())
.collect(Collectors.toList());
return childsValues;// return List<NodeResample> type
}
The complete TreeNodeResample class:
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
public class TreeNodeResample {
TreeNodeResample parent;
List<TreeNodeResample> children;
NodeResample value;
public TreeNodeResample(TreeNodeResample parent) {
this.parent = parent;
children = new ArrayList<>();
}
public TreeNodeResample(TreeNodeResample parent, NodeResample value) {
this.parent = parent;
children = new ArrayList<>();
this.value = value;
}
public void addChild(TreeNodeResample node) {
if (node != null && node.getValue() != null) {//REVIEW (node.getValue() != null) is needed?
if (children.stream().noneMatch(child -> Objects.equals(child.getValue(), node.getValue()))) {
children.add(node);
}
}
}
public TreeNodeResample getParent() {
return parent;
}
public void cleanChildren() {
children = new ArrayList<>();
}
public int getChildrenCount() {
return children.size();
}
public TreeNodeResample getChildrenAt(int position) {
if (children.size() > position && position > -1) {
return children.get(position);
}
return null;
}
public List<TreeNodeResample> getChildren() {
return children;
}
public NodeResample getValue() {
return value;
}
public boolean isLeaf() {
return (children.isEmpty());
}
public List<TreeNodeResample> getLeafs() {
return getLeafs(this);
}
public void addListValue(List<NodeResample> listValue) {
addListValue(this, listValue);
}
public TreeNodeResample getNode(NodeResample value) {
return getNode(this, value);
}
public List<NodeResample> getListValues() {
return getListNodes().stream().map(node -> node.getValue()).collect(Collectors.toList());
}
public List<TreeNodeResample> getListNodes() {
List<TreeNodeResample> listNodes = new ArrayList<>();
getListNodes(this, listNodes);
return listNodes;
}
public List<List<NodeResample>> getNestedListsValue() {
return getNestedListsValue(this);
}
public void setNestedListsValue(List<List<NodeResample>> nestedListsValue) {
setNestedListsValue(this, nestedListsValue);
}
public List<List<NodeResample>> getFilteredNestedListsValue(int sampleRateTarget) {
return getFilteredNestedListsValue(this, sampleRateTarget);
}
public TreeNodeResample getOptimizedTreeNodeResample(List<Integer> listSampleRateFinal) {
return getOptimizedTreeNodeResample(this, listSampleRateFinal);
}
public static void addListValue(TreeNodeResample parent, List<NodeResample> listValue) {
if (listValue != null) {
TreeNodeResample node = parent;
for (NodeResample child : listValue) {
node = getNode(node, child);
}
}
}
public static TreeNodeResample getNode(TreeNodeResample parent, NodeResample value) {
if (parent != null) {//REVIEW (value != null) is needed?
TreeNodeResample node = parent.getChildren().stream()
.filter(child -> child != null)
.filter(child -> Objects.equals(child.getValue(), value))
.findAny().orElse(null);
if (node != null) {
return node;
}
node = new TreeNodeResample(parent, value);
parent.addChild(node);
return node;
} else {
return null;
}
}
public static List<TreeNodeResample> getListNodes(TreeNodeResample parent) {
List<TreeNodeResample> listNodes = new ArrayList<>();
getListNodes(parent, listNodes);
return listNodes;
}
public static void getListNodes(TreeNodeResample parent, List<TreeNodeResample> listNodes) {
if (parent != null) {
listNodes.add(parent);
parent.getChildren().forEach(child -> getListNodes(child, listNodes));
}
}
public static List<List<NodeResample>> getNestedListsValue(TreeNodeResample parent) {
List<TreeNodeResample> listLeafs = getLeafs(parent);
List<List<NodeResample>> nestedListsValues = listLeafs.stream()
.map(leaf -> getParentsListValue(leaf))
.peek(listNodeResample -> {
//System.out.println(Arrays.toString(listNodeResample.toArray()) + System.lineSeparator() + System.lineSeparator());
})
.collect(Collectors.toList());
return nestedListsValues;
}
public static void setNestedListsValue(TreeNodeResample parent, List<List<NodeResample>> nestedListsValue) {
parent.cleanChildren();
nestedListsValue.stream()
.forEachOrdered(listValue -> {
addListValue(parent, listValue);
});
}
public static List<NodeResample> getParentsListValue(TreeNodeResample leaf) {
List<NodeResample> listValue = new ArrayList<>();
if (leaf != null) {
listValue.add(leaf.getValue());
TreeNodeResample node = leaf.getParent();
while (node != null && node.getValue() != null) {
listValue.add(0, node.getValue());
node = node.getParent();
}
}
return listValue;
}
public static List<List<NodeResample>> getFilteredNestedListsValue(TreeNodeResample parent, int sampleRateTarget) {
List<TreeNodeResample> listNodes = getListNodes(parent)
.stream()
.filter(treeNodeResample -> treeNodeResample.getValue() != null)
.filter(treeNodeResample -> treeNodeResample.getValue().getSampleRateTarget() == sampleRateTarget)
.collect(Collectors.toList());
List<List<NodeResample>> nestedListsValues = listNodes.stream()
.map(node -> getParentsListValue(node))
.collect(Collectors.toList());
return nestedListsValues;
}
private static TreeNodeResample getOptimizedTreeNodeResample(TreeNodeResample in, List<Integer> listSampleRateFinal) {
TreeNodeResample out = new TreeNodeResample(null);
listSampleRateFinal.forEach(sampleRateFinal -> {
List<List<NodeResample>> nestedListPerValue = getFilteredNestedListsValue(in, sampleRateFinal);
Long lastMinimum = Long.MAX_VALUE;
List<NodeResample> minimumlistPerValue = null;
for (List<NodeResample> listPerValue : nestedListPerValue) {
Long accumulator = addCalc(out.getNestedListsValue(), listPerValue)
.stream()
.map(nodeResample -> (long) nodeResample.getNumResampleOperations())
.mapToLong(Long::longValue).sum();
if (accumulator < lastMinimum) {
lastMinimum = accumulator;
minimumlistPerValue = listPerValue;
}
}
out.addListValue(minimumlistPerValue);
});
return out;
}
private static List<NodeResample> addCalc(List<List<NodeResample>> nestednestedListValue, List<NodeResample> listPerValue) {
TreeNodeResample temp = new TreeNodeResample(null);
temp.setNestedListsValue(nestednestedListValue);
temp.addListValue(listPerValue);
return temp.getListNodes().stream()
.map(node -> node.getValue())
.filter(nodeResample -> nodeResample != null)
.collect(Collectors.toList());
}
public static List<TreeNodeResample> getLeafs(TreeNodeResample parent) {
List<TreeNodeResample> listLeafs = new ArrayList<>();
getLeafs(parent, listLeafs);
return listLeafs;
}
private static void getLeafs(TreeNodeResample parent, List<TreeNodeResample> listLeafs) {
if (parent != null && listLeafs != null) {
if (parent.isLeaf()) {
listLeafs.add(parent);
} else {
parent.getChildren().forEach(child -> getLeafs(child, listLeafs));
}
}
}
#Override
public String toString() {
return "TreeNodeResample{" + "value=" + value + '}';
}
public static void tempPrintNested(List<List<NodeResample>> nestedListNodeResample) {
System.out.println(" List<List<NodeResample>> nestedListNodeResample = Arrays.asList(");
for (int o = 0; o < nestedListNodeResample.size(); o++) {
List<NodeResample> listNodeResample = nestedListNodeResample.get(o);
System.out.println(" Arrays.asList(");
for (int i = 0; i < listNodeResample.size(); i++) {
NodeResample nodeResample = listNodeResample.get(i);
if (nodeResample != null) {
System.out.print(" " + nodeResample.getCreator());
if (i < listNodeResample.size() - 1) {
System.out.println(",");
} else {
System.out.println("\n )");
}
}
}
if (o < nestedListNodeResample.size() - 1) {
System.out.println(" ,");
}
}
System.out.println(" );");
}
}
The another NodeResample class
public class NodeResample {
private int incrementL;
private int decrementM;
private int sampleRateSource;
private int sampleRateTarget;
private double maxPassFreq;
private Integer filterSize;
private Integer numResampleOperations;
public NodeResample(int incrementL, int decrementM, int sampleRateSource, int sampleRateTarget, double maxPassFreq, Integer filterSize, Integer numResampleOperations) {
this.incrementL = incrementL;
this.decrementM = decrementM;
this.sampleRateSource = sampleRateSource;
this.sampleRateTarget = sampleRateTarget;
this.maxPassFreq = maxPassFreq;
this.filterSize = filterSize;
this.numResampleOperations = numResampleOperations;
}
public int getIncrementL() {
return incrementL;
}
public void setIncrementL(int incrementL) {
this.incrementL = incrementL;
}
public int getDecrementM() {
return decrementM;
}
public void setDecrementM(int decrementM) {
this.decrementM = decrementM;
}
public int getSampleRateSource() {
return sampleRateSource;
}
public void setSampleRateSource(int sampleRateSource) {
this.sampleRateSource = sampleRateSource;
}
public int getSampleRateTarget() {
return sampleRateTarget;
}
public void setSampleRateTarget(int sampleRateTarget) {
this.sampleRateTarget = sampleRateTarget;
}
public double getMaxPassFreq() {
return maxPassFreq;
}
public void setMaxPassFreq(double maxPassFreq) {
this.maxPassFreq = maxPassFreq;
}
public Integer getFilterSize() {
return filterSize;
}
public void setFilterSize(Integer filterSize) {
this.filterSize = filterSize;
}
public Integer getNumResampleOperations() {
return numResampleOperations;
}
public void setNumResampleOperations(Integer numResampleOperations) {
this.numResampleOperations = numResampleOperations;
}
#Override
public String toString() {
return "NodeResample{" + "L=" + incrementL + ", M=" + decrementM
+ ", Source=" + sampleRateSource + ", Target=" + sampleRateTarget
+ ", filterSize=" + filterSize + ", numResampleOperations=" + numResampleOperations
+ "} ";
}
public String getCreator() {
return "new NodeResample(" + incrementL + "," + decrementM + "," + sampleRateSource + "," + sampleRateTarget + "," + "0.0" + "," + filterSize + "," + numResampleOperations
+ ")";
}
#Override
public int hashCode() {
int hash = 3;
return hash;
}
#Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final NodeResample other = (NodeResample) obj;
if (this.incrementL != other.incrementL) {
return false;
}
if (this.decrementM != other.decrementM) {
return false;
}
if (this.sampleRateSource != other.sampleRateSource) {
return false;
}
if (this.sampleRateTarget != other.sampleRateTarget) {
return false;
}
if (!Objects.equals(this.filterSize, other.filterSize)) {
return false;
}
return true;
}
}
I want to translate using Java Streams
But, I'm frustrated...
List<NodeResample> minimumlistPerValueNew = nestedListPerValue.stream()
.min(
Comparator.comparingLong(map(listPerValue -> {
TreeNodeResample temp = new TreeNodeResample(null);
temp.setNestedListsValue(out.getNestedListsValue());
temp.addListValue(listPerValue);
return temp.getListNodes();
})
//.map(node -> node::getValue)
.filter(nodeResample -> nodeResample != null)
.mapToLong(NodeResample::getNumResampleOperations).sum())
)
.orElse(Collections.emptyList());
RESUMED SITUATION
public CustomObject wrapperMethod(List<CustomObject> listCustomObjects) {
Long lastMinimum = Long.MAX_VALUE;
CustomObject minCustomObject;
for (CustomObject customObject : listCustomObjects) {
Long returnedValue = anyMethodReturningLong(customObject);
if (returnedValue < lastMinimum) {
lastMinimum = returnedValue;
minCustomObject = customObject;
}
}
return minCustomObject;
}
You can try Stream.reduce() also for your problem.
What I understand from your problem is that there is a nestedList and out of those inner Lists you want to return the list which matches your minimum criteria.
For e.g let say we have nested list like this [[1,2,4],[5,6,7,8,9,10],[11,12]] and now you want return the list with smallest list.size(). Try below code :
import java.util.*;
import java.util.stream.*;
public class Main
{
public static void main(String[] args) {
List<List<Integer>> nestedList = Arrays.asList(
Arrays.asList(1,2,4),
Arrays.asList(5,6,7,8,9,2,5),
Arrays.asList(10,11,12,13,0));
Optional<List<Integer>> oplist = nestedList.stream()
.reduce((list1, list2) -> list1.size() < list2.size() ? list1 : list2);
oplist.ifPresent(System.out::println);
}
}
Output : [1,2,4]
Hope you get the idea behind the approach. Now you can try comparison check inside reduce method and check if it works for you.
Solution for RESUMED SITUATION
//Using .reduce() method
Optional<CustomObject> minCustomObjectList = listCustomObjects.stream()
.reduce((lastMinimum, returnedValue) -> anyMethodReturningLong(returnedValue) < anyMethodReturningLong(lastMinimum) ? returnedValue : lastMinimum);
minCustomObjectList.ifPresent(e -> System.out.println("Minimum Object using reduce method "+e.toString()));
//Using .min() method
CustomObject minCustomObject = listCustomObjects.stream()
.min(Comparator.comparingLong(e -> anyMethodReturningLong(e))).get();
System.out.printf("Minimum Object using min method"+minCustomObject.toString());
For an assignment, I've been tasked to create a priority based support ticket system which contains the user's Name, ID, Handler and Priority however ticket's with higher priority are placed first in the list to be dealt with.
I have three classes.
Main: where I add/delete and change ticket priority.
TicketSystem: Contains the constructor for the ticket alongside getters and setter methods
LinkedList: Has insert, delete printList and should have sortList
So far I've determined the algorithm needs to be bubblesort as Priority is an int value but I'm not too sure how to receive the value for priority and then sort it.
public class TicketSystem {
private String handler;
private int priority;
private String iD;
private String creator;
public TicketSystem() {
}
public String getHandler ( ) {
return handler;
}
public int getPriority () {
return priority;
}
public String getID () {
return iD;
}
public String creator () {
return creator;
}
public void setID (String i) {
this.iD = i;
}
public void setHandler (String h) {
this.handler = h;
}
public void setPriority (int p ) {
this.priority = p;
}
public String setCreator (String c) {
return this.creator = c;
}
public void addTicket( String h, int p, String c, String iD) {
this.handler = h;
this.priority = p;
this.iD = iD;
this.creator = c;
}
#Override
public String toString() {
String output = "";
output += "Handler: " + handler +", ";
output += "Priority: " + priority + ", ";
output += "Creator: " + creator + ", ";
output += "ID: " + iD + " ";
return output;
}
}
public class LinkedList {
private Node head;
public LinkedList(TicketSystem ticket) {
head = new Node();
head.ticket = ticket;
head.link = null;
}
public boolean insertItem(TicketSystem ticket) {
Node n = new Node();
Node new_node;
new_node = head;
while (new_node.link != null) {
new_node = new_node.link;
}
n.ticket = ticket;
n.link = null;
new_node.link = n;
return true;
}
public void printList() {
Node z = head;
while (z!= null) {
System.out.println(z.ticket.toString());
z = z.link;
}
}
public boolean deleteItem(TicketSystem ticket) {
if(ticket.equals(head.ticket)) {
head = head.link;
return true;
} else {
Node prevNode = head;
Node curNode = head.link;
while(curNode != null && !(curNode.ticket == ticket)) {
prevNode = curNode;
curNode = curNode.link;
}
if(curNode != null) {
prevNode.link = curNode.link;
return true;
} else {
return false;
}
}
}
/* sort list */
public void sortList() {
TicketSystem ts = new TicketSystem();
}
class Node {
private TicketSystem ticket;
private Node link;
}
}
I'm trying to apply dynamic programming on a complete binary tree with 15 nodes, where each node is of type Employee and has a value(Evalution_Score) of type double and an ID.
I created an array of type double to store the max values. The method find returns the node with ID = j or I
public class BT<T> {
BTNode<T> root, current;
public BT() {
root = current = null;
}
public void max(){
BTNode<Employee> tmproot = (BTNode<Employee>)root;
BTNode<Employee> tmp=null;
double x[] = new double[33];
Employee p[] = new Employee[33];
for(int i=14;i>=0;i--) {
tmp = search(i+1, tmproot);
x[i] = Math.max(x[i+1], (tmp.data.Evaluation_Score + x[i+2+2]));
}
for(int j=14;j>=0;j--) {
tmp = search(j+1, tmproot);
if(x[j+1]<x[j])
p[j] = tmp.data;
}
for(Employee e: p)
System.out.println(e);
}
public BTNode<Employee> search(int id, BTNode<Employee> node){
if(node != null){
if(node.data.ID ==id){
return node;
} else {
BTNode<Employee> foundNode = search(id, node.left);
if(foundNode == null) {
foundNode = search(id, node.right);
}
return foundNode;
}
} else {
return null;
}
}
}
class BTNode <T> {
public T data;
public BTNode<T> left, right;
/** Creates a new instance of BTNode */
public BTNode(T val) {
data = val;
left = right = null;
}
public BTNode(T val, BTNode<T> l, BTNode<T> r){
data = val;
left = l;
right = r;
}
}
class Employee {
int ID_of_parent;
String Name;
int ID;
double Evaluation_Score;
public Employee(int ID_of_parent , String Name , int ID , double Evaluation_Score) {
this.ID_of_parent = ID_of_parent;
this.Name = Name;
this.ID = ID;
this.Evaluation_Score = Evaluation_Score;
}
public String toString() {
return ID_of_parent + ":" + Name + ":" + ID + ":" + Evaluation_Score + "\n";
}
}
But for some reason it's not printing the required output exactly.
I have a scenario where I get a string output from a service that returns a folder structure as below
id=0c06c81c8052324b;name=Documentation;type=root;|id=0b06c81c80524a87;name=ABC;type=folder;parent=0c06c81c8052324b;|id=0b06c81c80524837;name=Admin;type=folder;parent=0b06c81c80524a87;|id=0b06c81c8052483d;name=Admin 2.0;type=folder;parent=0b06c81c80524837;|id=0b06c81c8052483a;name=Panel;type=folder;parent=0b06c81c80524a87;|id=0b06c81c8052484a;name=VCM;type=folder;parent=0b06c81c8052483a;|id=0c06c81c80269e63;name=Invoices;type=root;|id=0b06c81c8026a008;name=other;type=folder;parent=0c06c81c80269e63;|id=0b06c81c8027a600;name=Workflow;type=folder;parent=0b06c81c8026a008;|id=0b06c81c8027a601;name=Worksheet;type=folder;parent=0b06c81c8027a600;|id=0c06c81c8051c7d3;name=Receipts;type=root;|id=0b06c81c80545f32;name=VR_2;type=folder;parent=0c06c81c8051c7d3;|id=0b06c81c80545f33;name=VR_3;type=folder;parent=0c06c81c8051c7d3;|id=0b06c81c80545f30;name=VR_1;type=folder;parent=0c06c81c8051c7d3;|id=0b06c81c8053486d;name=VR;type=folder;parent=0c06c81c8051c7d3;|id=0b06c81c80545f31;name=test2;type=folder;parent=0b06c81c8053486d;|id=0c06c81c8051c7d2;name=Source;type=root;|id=0b06c81c80524a8b;name=gem;type=folder;parent=0c06c81c8051c7d2;|id=0b06c81c80521681;name=Code;type=folder;parent=0b06c81c80524a8b;|id=0b06c81c8051cba7;name=pfm;type=folder;parent=0b06c81c80524a8b;
I was able to write a recursive logic to parse that string to come up with a structure as below:
Children of DCMGEN -> Documentation, ID: 0c06c81c8052324b
Children of DCMGEN -> Invoices, ID: 0c06c81c80269e63
Children of DCMGEN -> Source, ID: 0c06c81c8051c7d2
Children of DCMGEN -> Receipts, ID: 0c06c81c8051c7d3
Children of Documentation -> ABC, ID: 0b06c81c80524a87
Children of ABC -> Admin, ID: 0b06c81c80524837
Children of ABC -> Panel, ID: 0b06c81c8052483a
Children of Admin -> Admin 2.0, ID: 0b06c81c8052483d
Children of Panel -> VCM, ID: 0b06c81c8052484a
Children of Invoices -> other, ID: 0b06c81c8026a008
Children of other -> Workflow, ID: 0b06c81c8027a600
Children of Workflow -> Worksheet, ID: 0b06c81c8027a601
Children of Source -> gem, ID: 0b06c81c80524a8b
Children of gem -> Code, ID: 0b06c81c80521681
Children of gem -> pfm, ID: 0b06c81c8051cba7
Children of Receipts -> VR_2, ID: 0b06c81c80545f32
Children of Receipts -> VR_3, ID: 0b06c81c80545f33
Children of Receipts -> VR_1, ID: 0b06c81c80545f30
Children of Receipts -> VR, ID: 0b06c81c8053486d
Children of VR -> test2, ID: 0b06c81c80545f31
However, I want to create a folder structure from it on my local machine but am not able to create it recursively. Looking for some clues to solve this recursive problem. Can anyone please help ??
DCMGEN
Documentation
ABC
Admin
Admin 2.0
Panel
VCM
Invoices
other
Workflow
Worksheet
Source
gem
Code
pfm
Receipts
VR
test2
VR_1
VR_2
VR_3
Below is my code to get this far (with the help of some other thread on StackOverflow):
MegaMenuDTO.java
import java.util.ArrayList;
import java.util.List;
public class MegaMenuDTO {
private String Id;
private String name;
private String parentId;
private String type;
private List<MegaMenuDTO> childrenItems;
public MegaMenuDTO() {
this.Id = "";
this.name = "";
this.parentId = "";
this.childrenItems = new ArrayList<MegaMenuDTO>();
}
public String getId() {
return Id;
}
public void setId(String id) {
Id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getParentId() {
return parentId;
}
public void setParentId(String parentId) {
this.parentId = parentId;
}
public List<MegaMenuDTO> getChildrenItems() {
return childrenItems;
}
public void setChildrenItems(List<MegaMenuDTO> childrenItems) {
this.childrenItems = childrenItems;
}
public void addChildrenItem(MegaMenuDTO childrenItem){
if(!this.childrenItems.contains(childrenItem))
this.childrenItems.add(childrenItem);
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
#Override
public String toString() {
// return "MegaMenuDTO [Id=" + Id + ", name=" + name + ", parentId="
// + parentId + ", childrenItems=" + childrenItems + "]";
return "[name=" + name + ", childrenItems=" + childrenItems + "]";
}
}
MenuHelper.java
import java.io.File;
import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
public class MenuHelper {
private static final String TEMP_ROOT_FOLDER = "DCMGEN";
private static final String JAVA_IO_TMPDIR = "java.io.tmpdir";
private static final String FOLDERTREE_STR = "foldertree=";
private static final String RECORD_ELEMENT_DELIM = "[\\|]+";
private static final String SEPARATOR = System.getProperty("file.separator");
private static Map<String, List<MegaMenuDTO>> parentChildMap = new LinkedHashMap<String, List<MegaMenuDTO>>();
private static Map<String, String> idNameMap = new LinkedHashMap<String, String>();
//Test this helper class....
public static void main(String[] args) throws IOException {
final String FOLDER_STRUCTURE = "id=0c06c81c8052324b;name=Documentation;type=cabinet;|id=0b06c81c80524a87;name=ABC;type=folder;parent=0c06c81c8052324b;|id=0b06c81c80524837;name=Admin;type=folder;parent=0b06c81c80524a87;|id=0b06c81c8052483d;name=Admin 2.0;type=folder;parent=0b06c81c80524837;|id=0b06c81c8052483a;name=Panel;type=folder;parent=0b06c81c80524a87;|id=0b06c81c8052484a;name=VCM;type=folder;parent=0b06c81c8052483a;|id=0c06c81c80269e63;name=Invoices;type=cabinet;|id=0b06c81c8026a008;name=other;type=folder;parent=0c06c81c80269e63;|id=0b06c81c8027a600;name=Workflow;type=folder;parent=0b06c81c8026a008;|id=0b06c81c8027a601;name=Worksheet;type=folder;parent=0b06c81c8027a600;|id=0c06c81c8051c7d3;name=Receipts;type=cabinet;|id=0b06c81c80545f32;name=VR_2;type=folder;parent=0c06c81c8051c7d3;|id=0b06c81c80545f33;name=VR_3;type=folder;parent=0c06c81c8051c7d3;|id=0b06c81c80545f30;name=VR_1;type=folder;parent=0c06c81c8051c7d3;|id=0b06c81c8053486d;name=VR;type=folder;parent=0c06c81c8051c7d3;|id=0b06c81c80545f31;name=test2;type=folder;parent=0b06c81c8053486d;|id=0c06c81c8051c7d2;name=Source;type=root;|id=0b06c81c80524a8b;name=gem;type=folder;parent=0c06c81c8051c7d2;|id=0b06c81c80521681;name=Code;type=folder;parent=0b06c81c80524a8b;|id=0b06c81c8051cba7;name=pfm;type=folder;parent=0b06c81c80524a8b;";
System.out.println("Temp folder : " + System.getProperty(JAVA_IO_TMPDIR));
List<FolderObj> folders = MenuHelper.parseResponseString(FOLDER_STRUCTURE);
if(folders != null) {
List<MegaMenuDTO> menuDTOList = MenuHelper.prepareMenu(folders);
List<File> rootDirs = new ArrayList<>();
File rootDir = new File(System.getProperty(JAVA_IO_TMPDIR) + SEPARATOR + TEMP_ROOT_FOLDER);
//Check and Delete the root folder, if present, before processing.
if(rootDir.exists()) {
rootDirs.add(rootDir);
for(File file : rootDirs) {
recursivelyDelete(file);
}
}
//Create a fresh root dir.
rootDirs.clear();
rootDir = createTempRootDir(TEMP_ROOT_FOLDER);
rootDirs.add(rootDir);
//System.out.println("Tree : " + menuDTOList);
for(MegaMenuDTO mmd: menuDTOList){
printMenu(mmd, "\t");
captureIdNameMap(mmd);
printPaths(mmd, TEMP_ROOT_FOLDER + SEPARATOR + mmd.getName());
}
for (Map.Entry<String, List<MegaMenuDTO>> entry : parentChildMap.entrySet()) {
String key = entry.getKey();
List<MegaMenuDTO> value = entry.getValue();
for(MegaMenuDTO dto : value) {
if(idNameMap.get(key) == null) {
System.out.println("Children of " + key + " -> " + dto.getName() + ", ID: " + dto.getId());
} else {
System.out.println("Children of " + idNameMap.get(key) + " -> " + dto.getName() + ", ID: " + dto.getId());
}
}
}
}
}
public static List<FolderObj> parseResponseString(final String input) {
if(input == null) {
return null;
}
List<FolderObj> menuList = new ArrayList<>();
String[] parsedValues = input.split(RECORD_ELEMENT_DELIM);
for(short i=0; i < parsedValues.length; i++) {
menuList.add(digest(filterValue(parsedValues[i])));
}
return menuList;
}
public static String filterValue(String input) {
if(input == null) {
return input;
}
if(input.contains(FOLDERTREE_STR)) {
input = input.substring(input.indexOf(FOLDERTREE_STR) + FOLDERTREE_STR.length());
}
return input;
}
public static FolderObj digest(String input) {
if(input == null) {
return null;
}
Map<String, String> holder = new HashMap<>();
String [] keyVals = input.split(";");
for(String keyVal : keyVals) {
String [] parts = keyVal.split("=");
holder.put(parts[0], parts[1]);
}
FolderObj folderObj = null;
String childId = null;
String name = null;
String type = null;
String parentId = null;
for(Map.Entry<String, String> entry : holder.entrySet()) {
String key = entry.getKey();
if(key.equals("id")) {
childId = entry.getValue();
} else if(key.equals("name")) {
name = entry.getValue();
} else if(key.equals("type")) {
type = entry.getValue();
} else if(key.equals("parent")) {
parentId = entry.getValue();
}
folderObj = new FolderObj(childId, parentId, name, type);
}
return folderObj;
}
public static List<MegaMenuDTO> prepareMenu(List<FolderObj> folderList) {
// Arrange String corresponds to the Id
Map<String, MegaMenuDTO> megaMenuMap = new HashMap<>();
// populate a Map
for(FolderObj folderObj: folderList){
// ----- Child -----
MegaMenuDTO mmdChild;
if(megaMenuMap.containsKey(folderObj.getChildId())){
mmdChild = megaMenuMap.get(folderObj.getChildId());
}
else{
mmdChild = new MegaMenuDTO();
megaMenuMap.put(folderObj.getChildId(),mmdChild);
}
mmdChild.setId(folderObj.getChildId());
mmdChild.setParentId(folderObj.getParentId());
mmdChild.setName(folderObj.getName());
mmdChild.setType(folderObj.getType());
// no need to set ChildrenItems list because the constructor created a new empty list
// ------ Parent ----
MegaMenuDTO mmdParent;
if(megaMenuMap.containsKey(folderObj.getParentId())){
mmdParent = megaMenuMap.get(folderObj.getParentId());
}
else{
mmdParent = new MegaMenuDTO();
megaMenuMap.put(folderObj.getParentId(),mmdParent);
}
mmdParent.setId(folderObj.getParentId());
// mmdParent.setParentId(null);
mmdParent.addChildrenItem(mmdChild);
}
// Get the root
List<MegaMenuDTO> menuList = new ArrayList<MegaMenuDTO>();
for(MegaMenuDTO megaMenuDTO : megaMenuMap.values()){
if(megaMenuDTO.getParentId() == null)
menuList.add(megaMenuDTO);
}
return menuList;
}
private static void printMenu(MegaMenuDTO dto, String tabValue) {
for(MegaMenuDTO childDTO : dto.getChildrenItems()) {
System.out.println(tabValue + childDTO.getName());
tabValue = "\t" + tabValue;
printMenu(childDTO, tabValue);
}
}
private static void captureIdNameMap(MegaMenuDTO dto) throws IOException {
idNameMap.put(dto.getId(), dto.getName());
for(MegaMenuDTO childDTO : dto.getChildrenItems()) {
idNameMap.put(childDTO.getId(), childDTO.getName());
captureIdNameMap(childDTO);
}
}
private static void printPaths(MegaMenuDTO dto, String name) throws IOException {
if(dto.getParentId() == null) {
if(parentChildMap.get("ROOT") == null) {
List<MegaMenuDTO> parentList = new ArrayList<MegaMenuDTO>();
parentList.add(dto);
parentChildMap.put("ROOT", parentList);
} else {
List<MegaMenuDTO> parentList = parentChildMap.get("ROOT");
parentList.add(dto);
parentChildMap.put("ROOT", parentList);
}
}
for(MegaMenuDTO childDTO : dto.getChildrenItems()) {
if (parentChildMap.get(childDTO.getParentId()) == null) {
List<MegaMenuDTO> parentList = new ArrayList<MegaMenuDTO>();
parentList.add(childDTO);
parentChildMap.put(childDTO.getParentId(), parentList);
} else {
List<MegaMenuDTO> parentList = parentChildMap.get(childDTO.getParentId());
parentList.add(childDTO);
parentChildMap.put(childDTO.getParentId(), parentList);
}
System.out.println(name + SEPARATOR + childDTO.getName() + ", ParentId : " + childDTO.getParentId());
createTempRootDir(name + SEPARATOR + childDTO.getName());
name = name + SEPARATOR + childDTO.getName();
printPaths(childDTO, name);
}
}
public static File createTempRootDir(String name) throws IOException {
final File sysTempDir = new File(System.getProperty(JAVA_IO_TMPDIR));
File newTempDir = new File(sysTempDir, name);
if (newTempDir.mkdirs()) {
return newTempDir;
} else {
throw new IOException("Failed to create temp dir named " + newTempDir.getAbsolutePath());
}
}
/**
* Recursively delete file or directory
*
* #param fileOrDir
* the file or dir to delete
* #return true iff all files are successfully deleted
*/
public static void recursivelyDelete(File fileOrDir) throws IOException {
Path directory = Paths.get(fileOrDir.getAbsolutePath());
Files.walkFileTree(directory, new SimpleFileVisitor<Path>() {
#Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
Files.delete(file);
return FileVisitResult.CONTINUE;
}
#Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
Files.delete(dir);
return FileVisitResult.CONTINUE;
}
});
}
}
Finally got it to work after reading up more on recursion. Below is the new updated code for anyone trying to do something similar. Not claiming that this is the most efficient or shortest code possible but the best I could come up with. If someone has an improved version, I would be very happy to see that.
MenuHelper.java
public class MenuHelper {
private static final String TEMP_ROOT_FOLDER = "DCMGEN";
private static final String JAVA_IO_TMPDIR = "java.io.tmpdir";
private static final String FOLDERTREE_STR = "foldertree=";
private static final String RECORD_ELEMENT_DELIM = "[\\|]+";
private static final String SEPARATOR = System.getProperty("file.separator");
private static Map<String, List<MegaMenuDTO>> parentChildMap = new LinkedHashMap<String, List<MegaMenuDTO>>();
private static Map<String, String> idNameMap = new LinkedHashMap<String, String>();
//Test this helper class....
public static void main(String[] args) throws IOException {
final String FOLDER_STRUCTURE = "id=0c06c81c8052324b;name=Documentation;type=cabinet;|id=0b06c81c80524a87;name=ABC;type=folder;parent=0c06c81c8052324b;|id=0b06c81c80524837;name=Admin;type=folder;parent=0b06c81c80524a87;|id=0b06c81c8052483d;name=Admin 2.0;type=folder;parent=0b06c81c80524837;|id=0b06c81c8052483a;name=Panel;type=folder;parent=0b06c81c80524a87;|id=0b06c81c8052484a;name=VCM;type=folder;parent=0b06c81c8052483a;|id=0c06c81c80269e63;name=Invoices;type=cabinet;|id=0b06c81c8026a008;name=other;type=folder;parent=0c06c81c80269e63;|id=0b06c81c8027a600;name=Workflow;type=folder;parent=0b06c81c8026a008;|id=0b06c81c8027a601;name=Worksheet;type=folder;parent=0b06c81c8027a600;|id=0c06c81c8051c7d3;name=Receipts;type=cabinet;|id=0b06c81c80545f32;name=VR_2;type=folder;parent=0c06c81c8051c7d3;|id=0b06c81c80545f33;name=VR_3;type=folder;parent=0c06c81c8051c7d3;|id=0b06c81c80545f30;name=VR_1;type=folder;parent=0c06c81c8051c7d3;|id=0b06c81c8053486d;name=VR;type=folder;parent=0c06c81c8051c7d3;|id=0b06c81c80545f31;name=test2;type=folder;parent=0b06c81c8053486d;|id=0c06c81c8051c7d2;name=Source;type=root;|id=0b06c81c80524a8b;name=gem;type=folder;parent=0c06c81c8051c7d2;|id=0b06c81c80521681;name=Code;type=folder;parent=0b06c81c80524a8b;|id=0b06c81c8051cba7;name=pfm;type=folder;parent=0b06c81c80524a8b;";
System.out.println("Temp folder : " + System.getProperty(JAVA_IO_TMPDIR));
List<FolderObj> folders = MenuHelper.parseResponseString(FOLDER_STRUCTURE);
if(folders != null) {
List<MegaMenuDTO> menuDTOList = MenuHelper.prepareMenu(folders);
List<File> rootDirs = new ArrayList<>();
File rootDir = new File(System.getProperty(JAVA_IO_TMPDIR) + SEPARATOR + TEMP_ROOT_FOLDER);
//Check and Delete the root folder, if present, before processing.
if(rootDir.exists()) {
rootDirs.add(rootDir);
for(File file : rootDirs) {
recursivelyDelete(file);
}
}
//Create a fresh root dir.
rootDirs.clear();
rootDir = createTempRootDir(TEMP_ROOT_FOLDER);
rootDirs.add(rootDir);
//System.out.println("Tree : " + menuDTOList);
for(MegaMenuDTO mmd: menuDTOList){
printMenu(mmd, "\t");
captureIdNameMap(mmd);
printPaths(mmd, TEMP_ROOT_FOLDER + SEPARATOR + mmd.getName());
}
for (Map.Entry<String, List<MegaMenuDTO>> entry : parentChildMap.entrySet()) {
String key = entry.getKey();
List<MegaMenuDTO> value = entry.getValue();
for(MegaMenuDTO dto : value) {
if(idNameMap.get(key) == null) {
System.out.println("Children of " + key + " -> " + dto.getName() + ", ID: " + dto.getId());
} else {
System.out.println("Children of " + idNameMap.get(key) + " -> " + dto.getName() + ", ID: " + dto.getId());
}
}
}
System.out.println("--------------------------------------\n");
for (Map.Entry<String, List<MegaMenuDTO>> entry : parentChildMap.entrySet()) {
String key = entry.getKey();
List<MegaMenuDTO> value = entry.getValue();
if(key.equals("ROOT")) {
for(MegaMenuDTO dto : value) {
System.out.println("Root Folder is : " + dto.getName());
//createTempRootDir(TEMP_ROOT_FOLDER + SEPARATOR + dto.getName());
System.out.println(TEMP_ROOT_FOLDER + SEPARATOR + dto.getName());
printFoldersRecursively(parentChildMap.get(dto.getId()), TEMP_ROOT_FOLDER + SEPARATOR + dto.getName());
}
}
}
}
}
public static void printFoldersRecursively(List<MegaMenuDTO> value, String rootPath) throws IOException {
for (MegaMenuDTO inDTO1 : value) {
System.out.println(rootPath + SEPARATOR + inDTO1.getName());
for(MegaMenuDTO childItem : inDTO1.getChildrenItems()) {
System.out.println(rootPath + SEPARATOR + inDTO1.getName() + SEPARATOR + childItem.getName());
printFoldersRecursively(childItem.getChildrenItems(), rootPath + SEPARATOR + inDTO1.getName() + SEPARATOR + childItem.getName());
}
}
}
public static List<FolderObj> parseResponseString(final String input) {
if(input == null) {
return null;
}
List<FolderObj> menuList = new ArrayList<>();
String[] parsedValues = input.split(RECORD_ELEMENT_DELIM);
for(short i=0; i < parsedValues.length; i++) {
menuList.add(digest(filterValue(parsedValues[i])));
}
return menuList;
}
public static String filterValue(String input) {
if(input == null) {
return input;
}
if(input.contains(FOLDERTREE_STR)) {
input = input.substring(input.indexOf(FOLDERTREE_STR) + FOLDERTREE_STR.length());
}
return input;
}
public static FolderObj digest(String input) {
if(input == null) {
return null;
}
Map<String, String> holder = new HashMap<>();
String [] keyVals = input.split(";");
for(String keyVal : keyVals) {
String [] parts = keyVal.split("=");
holder.put(parts[0], parts[1]);
}
FolderObj folderObj = null;
String childId = null;
String name = null;
String type = null;
String parentId = null;
for(Map.Entry<String, String> entry : holder.entrySet()) {
String key = entry.getKey();
if(key.equals("id")) {
childId = entry.getValue();
} else if(key.equals("name")) {
name = entry.getValue();
} else if(key.equals("type")) {
type = entry.getValue();
} else if(key.equals("parent")) {
parentId = entry.getValue();
}
folderObj = new FolderObj(childId, parentId, name, type);
}
return folderObj;
}
public static List<MegaMenuDTO> prepareMenu(List<FolderObj> folderList) {
// Arrange String corresponds to the Id
Map<String, MegaMenuDTO> megaMenuMap = new HashMap<>();
// populate a Map
for(FolderObj folderObj: folderList){
MegaMenuDTO mmdChild;
if(megaMenuMap.containsKey(folderObj.getChildId())){
mmdChild = megaMenuMap.get(folderObj.getChildId());
} else{
mmdChild = new MegaMenuDTO();
megaMenuMap.put(folderObj.getChildId(),mmdChild);
}
mmdChild.setId(folderObj.getChildId());
mmdChild.setParentId(folderObj.getParentId());
mmdChild.setName(folderObj.getName());
mmdChild.setType(folderObj.getType());
// ------ Parent ----
MegaMenuDTO mmdParent;
if(megaMenuMap.containsKey(folderObj.getParentId())){
mmdParent = megaMenuMap.get(folderObj.getParentId());
} else{
mmdParent = new MegaMenuDTO();
megaMenuMap.put(folderObj.getParentId(),mmdParent);
}
mmdParent.setId(folderObj.getParentId());
mmdParent.addChildrenItem(mmdChild);
}
// Get the root
List<MegaMenuDTO> menuList = new ArrayList<MegaMenuDTO>();
for(MegaMenuDTO megaMenuDTO : megaMenuMap.values()){
if(megaMenuDTO.getParentId() == null)
menuList.add(megaMenuDTO);
}
return menuList;
}
private static void printMenu(MegaMenuDTO dto, String tabValue) {
for(MegaMenuDTO childDTO : dto.getChildrenItems()) {
System.out.println(tabValue + childDTO.getName());
tabValue = "\t" + tabValue;
printMenu(childDTO, tabValue);
}
}
private static void captureIdNameMap(MegaMenuDTO dto) throws IOException {
idNameMap.put(dto.getId(), dto.getName());
for(MegaMenuDTO childDTO : dto.getChildrenItems()) {
idNameMap.put(childDTO.getId(), childDTO.getName());
captureIdNameMap(childDTO);
}
}
private static void printPaths(MegaMenuDTO dto, String name) throws IOException {
if(dto.getParentId() == null) {
if(parentChildMap.get("ROOT") == null) {
List<MegaMenuDTO> parentList = new ArrayList<MegaMenuDTO>();
parentList.add(dto);
parentChildMap.put("ROOT", parentList);
} else {
List<MegaMenuDTO> parentList = parentChildMap.get("ROOT");
parentList.add(dto);
parentChildMap.put("ROOT", parentList);
}
}
for(MegaMenuDTO childDTO : dto.getChildrenItems()) {
if (parentChildMap.get(childDTO.getParentId()) == null) {
List<MegaMenuDTO> parentList = new ArrayList<MegaMenuDTO>();
parentList.add(childDTO);
parentChildMap.put(childDTO.getParentId(), parentList);
} else {
List<MegaMenuDTO> parentList = parentChildMap.get(childDTO.getParentId());
parentList.add(childDTO);
parentChildMap.put(childDTO.getParentId(), parentList);
}
System.out.println(name + SEPARATOR + childDTO.getName() + ", ParentId : " + childDTO.getParentId());
createTempRootDir(name + SEPARATOR + childDTO.getName());
name = name + SEPARATOR + childDTO.getName();
printPaths(childDTO, name);
}
}
public static File createTempRootDir(String name) throws IOException {
final File sysTempDir = new File(System.getProperty(JAVA_IO_TMPDIR));
File newTempDir = new File(sysTempDir, name);
if (newTempDir.mkdirs()) {
return newTempDir;
} else {
throw new IOException("Failed to create temp dir named " + newTempDir.getAbsolutePath());
}
}
/**
* Recursively delete file or directory
*
* #param fileOrDir
* the file or dir to delete
* #return true iff all files are successfully deleted
*/
public static void recursivelyDelete(File fileOrDir) throws IOException {
Path directory = Paths.get(fileOrDir.getAbsolutePath());
Files.walkFileTree(directory, new SimpleFileVisitor<Path>() {
#Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
Files.delete(file);
return FileVisitResult.CONTINUE;
}
#Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
Files.delete(dir);
return FileVisitResult.CONTINUE;
}
});
}
}
I would like to create and print a tree from string which read from file. I tried the following code but I could not print the tree in a correct way.
I have file file.txt which has for example the following string
com-bo-news-2012,12
com-bo-news-2015,3
net-php-www,20
net-phototrails,3
I would like to create a tree like
root
|
com(17) //calculated as (2+12+3)
|bo(17)
|news(17)
|2012 (12)
|2015(3)
|net(23)
|php(20)
|www(20)
|phototrails(3)
I tried the following code
public void ReadFile(String inputFile){
Map<String[],Integer> map = new HashMap<String[], Integer>();
BufferedReader br=null;
String file1 = "";
try {
br = new BufferedReader(new FileReader(inputFile));
while ((file1 = br.readLine()) != null) {
String path[]=file1.split(",");
String nodes[]=path[0].split("-");
map.put(nodes,Integer.parseInt(path[1].trim()));
}
buildTree(map);
br.close();
}catch(Exception e){
System.out.println(e);
}
}
public void buildTree(Map<String[],Integer> map)
{
Map<String, Node> wordMap = new HashMap<String, Node>();
Node root = new Node();
for (Map.Entry<String[], Integer> entry : map.entrySet()) {
String key[] = entry.getKey();
Integer value = entry.getValue();
Node current=root;
Node p;
for(String node:key)
{
if(wordMap.containsKey(node)){
p = wordMap.get(node);
p.addCost(value);
} else {
p=new Node(node,value);
wordMap.put(node, p);
System.out.println("AddNode: "+p.getName());
}
current.addChild(p);
current = p;
}
}
printTree(root);
}
public void printTree(Node doc) { ///print tree
if (doc == null) {
System.out.println("Nothing to print!!");
return;
}
try {
System.out.println(doc.getName() + " " + doc.getCount());
List<Node> cl = doc.getChildren();
for (int i = 0; i < cl.size(); i++) {
Node node = cl.get(i);
System.out.println(
"\t" + node.getName() + " ->" + node.getCount());
}
List<Node> nl = doc.getChildren();
for (int i = 0; i < nl.size(); i++) {
Node node = nl.get(i);
printTree(node);
}
} catch (Throwable e) {
System.out.println("Cannot print!! " + e.getMessage());
}
}
public class Node {
private String name;
private int count;
private List<Node> children;
public Node() {
this(null, 0);
}
public Node(String name, int count) {
this.name = name;
this.count = count;
this.children = new ArrayList<Node>();
}
public Node(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public List<Node> getChildren() {
return children;
}
public void setChildren(List<Node> children) {
this.children = children;
}
public void addChild(Node n) {
for (Node nn : children) {
if (nn.name.equals(n.name)) {
return;
}
}
this.children.add(n);
}
public void addCost(int i) {
this.count += i;
}
}
But I could not print the tree in a correct way which mentioned. It sometimes make a infinite loop when it will get same node as a child. Could anyone please guide me for that? Thanks.
I have added the code to generate the Tree kind of structure, have used the composite pattern.
package com.test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class TestMain {
public static void main(String[] args) {
TestMain testMain = new TestMain();
List<String> testData = new ArrayList<String>();
testData.add("com-bo-news-2012,12");
testData.add("com-bo-news-2015,3");
testData.add("net-php-www,20");
testData.add("net-phototrails,3");
MyNode myNode = new MyNode("ROOT");
for (String string : testData) {
List<String> l = new ArrayList<String>();
l.addAll(Arrays.asList(string.split("-")));
testMain.buildTree(l, myNode);
}
printTree(myNode, 1);
}
private void buildTree(List<String> nodeNames, MyNode node) {
if (nodeNames.isEmpty()) {
return;
}
String nodeName = nodeNames.remove(0);
MyNode myNode = new MyNode(nodeName);
int index = node.getNodes().indexOf(myNode);
if (index == -1) {
node.getNodes().add(myNode);
} else {
myNode = node.getNodes().get(index);
}
buildTree(nodeNames, myNode);
}
private static void printTree(MyNode myNode, int tabCount) {
for (int i = 0; i < tabCount; i++) {
System.out.print("\t");
}
System.out.print(myNode.getNode() + "\n");
for (int i = 0; i < tabCount; i++) {
System.out.print("\t");
}
System.out.println("|");
for (MyNode node : myNode.getNodes()) {
printTree(node, ++tabCount);
}
}
}
package com.test;
import java.util.ArrayList;
import java.util.List;
public class MyNode {
private String node;
private List<MyNode> nodes;
public MyNode(String node) {
super();
this.node = node;
this.nodes = new ArrayList<MyNode>();
}
public MyNode(String node, List<MyNode> nodes) {
super();
this.node = node;
this.nodes = nodes;
}
public String getNode() {
return node;
}
public void setNode(String node) {
this.node = node;
}
public List<MyNode> getNodes() {
return nodes;
}
public void setNodes(List<MyNode> nodes) {
this.nodes = nodes;
}
#Override
public int hashCode() {
return node.hashCode();
}
#Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass().equals(obj.getClass())) {
return ((MyNode) obj).getNode().equals(node);
}
return false;
}
#Override
public String toString() {
return node + "[" + nodes.size()+"]";
}
}
Output needs to be formatted a bit, let me know if you have any questions