Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I need to convert these type of strings which are stored in an ArrayList :
Alpha.Beta.Com.
Alpa.Xeta.Hash.
Alpha.Eta.Dot.
Alpha.Eta.Comma.
Alpha.Eta.Dollar.
Alpha.Xeta.Tilde
Alpha.Beta.Com.Xeta.
here Alpha.Beta.Com. will have Xeta as child ,but Xeta must not have Hash and Tilde as children in this object.
Only,Alpha.Xeta object will have Hash and Tilde as children
these strings are like tree like structure(n levels) which means ,Alpha has Beta,Xeta & Eta as Child.
Furthermore,Beta has Com,
Xeta has Hash & Tilde,
Eta has Comma,Dollar & Dot as child.
We need to identify each parent and child using java program and then build it to XML.
Check this:
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class StringsToXmlConverter {
private static final String SEPARTOR = "\\.";
List<String> list;
Map<String, XmlElement> elements = new HashMap<String,XmlElement>();
public StringsToXmlConverter(List<String> list) {
this.list = list;
}
public String getXml() {
for (String xmlPaths: list) {
String[] splitedElements = xmlPaths.split(SEPARTOR);
XmlElement parent = null;
for (String elem : splitedElements) {
XmlElement currentElem = null;
if (elements.containsKey(elem)) {
currentElem = elements.get(elem);
if (parent != null) {
addChild(parent, currentElem);
}
} else {
currentElem = createNewElement(parent, elem);
elements.put(elem, currentElem);
}
parent = currentElem;
}
}
return buildXml().toString();
}
private void addChild(XmlElement parent, XmlElement currentElem) {
currentElem.parent = parent;
parent.childs.add(currentElem);
}
private XmlElement createNewElement(XmlElement parent, String name) {
XmlElement currentElem;
currentElem = new XmlElement();
currentElem.name = name;
if (parent != null) {
addChild(parent, currentElem);
}
return currentElem;
}
private StringBuilder buildXml() {
StringBuilder xml = new StringBuilder();
for(XmlElement elem : elements.values()) {
if (elem.parent == null) {
xml.append(elem.toXml());
}
}
return xml;
}
private class XmlElement {
String name;
Set<XmlElement> childs = new HashSet<XmlElement>();
XmlElement parent = null;
boolean isPrinted = false;
private Set<XmlElement> getNoPrintedChilds() {
Set<XmlElement> notPrintedChilds = new HashSet<XmlElement>();
Iterator<XmlElement> iterator = childs.iterator();
while(iterator.hasNext()) {
XmlElement node = iterator.next();
if (!node.isPrinted) {
notPrintedChilds.add(node);
}
}
return notPrintedChilds;
}
public String toXml() {
StringBuilder xml = new StringBuilder();
if (!isPrinted) {
xml.append("<" + name);
if (getNoPrintedChilds().isEmpty()) {
xml.append("/>");
} else {
xml.append(">");
for (XmlElement elem : getNoPrintedChilds()) {
xml.append(elem.toXml());
}
xml.append("</" + name + ">");
}
}
isPrinted = true;
return xml.toString();
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + getOuterType().hashCode();
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
XmlElement other = (XmlElement) obj;
if (!getOuterType().equals(other.getOuterType()))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
private StringsToXmlConverter getOuterType() {
return StringsToXmlConverter.this;
}
}
public static void main(String[] args) {
List<String> list= Arrays.asList("Alpha.Beta.Com",
"Alpha.Xeta.Hash",
"Alpha.Eta.Dot",
"Alpha.Eta.Comma",
"Alpha.Eta.Dollar",
"Alpha.Xeta.Tilde");
StringsToXmlConverter converter = new StringsToXmlConverter(list);
System.out.println(converter.getXml());
}
}
Related
I have found few similar threads about infinity loop while trying save object as Json, but most of them are about java + jpa, and these solutions don't work for me. I would like to create tree structure of some data. There is class ProjectNode which got
private ArrayList<ProjectNode> children;
field. I'm pretty sure this one course the problem but its the main field in this structure, I can't ignore it. I have tested and I can convert object which has list with node which doesn't have children, but cant if any child got another children in the below code:
public class ProjectNode implements Comparable<ProjectNode>{
private String parent;
private String nodeName;
private String nodeHref;
private boolean hasChild;
private int td;
private ArrayList<ProjectNode> children;
public ProjectNode() {
super();
// TODO Auto-generated constructor stub
}
+ getters and setters
ObjectMapper objectMapper = new ObjectMapper();
String json = objectMapper.writeValueAsString(parser.getProjectFactory().get(12));
parser.getProjectFactory() returns list of ParentNodes (parent=null), I would like to convert 12 elements because there is a case where node has child and this child has child. Cause this error:
Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (StackOverflowError) (through reference chain: java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"])
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:734)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155)
at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serializeContents(IndexedListSerializer.java:119)
at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serialize(IndexedListSerializer.java:79)
at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serialize(IndexedListSerializer.java:18)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:727)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:719)
EDIT:
Parser - parse project/hosts list from cacti:
public List<ProjectNode> getProjectFactory() throws FailingHttpStatusCodeException, MalformedURLException, IOException {
FileWriter fstream = new FileWriter("graphMap.txt");
BufferedWriter out = new BufferedWriter(fstream);
String [] hostInfo = null;
HtmlTableCell cel= (HtmlTableCell) page.getHtmlPage().getByXPath("/html/body/table/tbody/tr[5]/td[1]").get(0);
System.out.println(cel.getChildElementCount());
List<HtmlDivision> divs = cel.getByXPath(".//div");
System.out.println(divs.size());
//checks if list of host has been added to the project
ProjectTree projectTree = new ProjectTree();
Map<Integer,String> suppMap = new HashMap<Integer,String>();
for(HtmlDivision div : divs) {
List<DomNode> td = div.getByXPath(".//table/tbody/tr/td");
if(td.size()>2) {
ProjectNode pn = new ProjectNode(getNameSrc(td).split("#")[0],getNameSrc(td).split("#")[1],td.size());
hostInfo = getNameSrc(td).split("#");
if(pn.getTd()>3) {
if(!suppMap.get(pn.getTd()-1).isEmpty()) {
pn.setParent(suppMap.get(pn.getTd()-1));
}
if(suppMap.get(pn.getTd())!=null){
suppMap.remove(pn.getTd());
}
suppMap.put(pn.getTd(), pn.getNodeName());
projectTree.addNodeToTree(pn);
} else {
projectTree.addNodeToTree(pn);
suppMap.put(pn.getTd(), pn.getNodeName());
//out.write(pn.toString()+"\n");
}
}
}
ArrayList<ProjectNode> pns = projectTree.getNodeList();
Collections.sort(pns, Comparator.comparing(ProjectNode::getTd));
Collections.reverse(pns);
projectTree.setNodeList(pns);
List<ProjectNode> finalList = new ArrayList<ProjectNode>();
for(ProjectNode pn :pns ) {
if(pn.getTd()==3) {
finalList.add(pn);
}else {
projectTree.addToParent(pn);
}
}
Collections.reverse(finalList);
for(ProjectNode pn : finalList) {
Collections.sort(pn.getChildren());
}
out.write(finalList.get(12).getChildren().get(4).getChildren().toString());
out.close();
System.out.println(finalList.size());
return finalList;
}
ProjectTree class
public class ProjectTree {
private ProjectNode rootNode;
private ArrayList<ProjectNode> NodeList;
public ProjectTree() {
super();
this.NodeList = new ArrayList<ProjectNode>();
}
public ProjectTree(ProjectNode rootNode, ArrayList<ProjectNode> nodeList) {
super();
this.rootNode = rootNode;
NodeList = nodeList;
}
public ArrayList<ProjectNode> groupHosts(){
return this.NodeList;
}
public void addToParent(ProjectNode pn) {
for(ProjectNode pnA :this.NodeList) {
if(pnA.getNodeName().equals(pn.getParent())) {
if(pnA.getChildren()!=null && pnA.getChildren().size()!=0) {
pnA.sortChildren();
}
pnA.addChlild(pn);
}
}
}
public ProjectNode getRootNode() {
return rootNode;
}
public void setRootNode(ProjectNode rootNode) {
this.rootNode = rootNode;
}
public ArrayList<ProjectNode> getNodeList() {
return NodeList;
}
public void setNodeList(ArrayList<ProjectNode> nodeList) {
NodeList = nodeList;
}
}
ProjectNode.class
public class ProjectNode implements Comparable<ProjectNode>{
private String parent;
private String nodeName;
private String nodeHref;
private boolean hasChild;
private int td;
private ArrayList<ProjectNode> children;
public ProjectNode() {
super();
// TODO Auto-generated constructor stub
}
public ProjectNode( String nodeName, String nodeHref, int td) {
super();
this.nodeName = nodeName;
this.nodeHref = nodeHref;
this.hasChild =false;
this.td=td;
}
public void addChlild(ProjectNode pn) {
if(children!=null) {
this.children.add(pn);
}else {
this.children = new ArrayList<ProjectNode>();
this.children.add(pn);
}
}
public List<ProjectNode> getChildren() {
return children;
}
public void sortChildren() {
Collections.sort(this.getChildren());;
//Collections.sort(this.getChildren(), Comparator.comparing(ProjectNode::getNodeName));
//System.out.println(this.children.toString());
}
public void setChildren(ArrayList<ProjectNode> children) {
this.children = children;
}
public int getTd() {
return td;
}
public void setTd(int td) {
this.td = td;
}
public boolean isHasChild() {
return hasChild;
}
public void setHasChild(boolean hasChild) {
this.hasChild = hasChild;
}
public String getParent() {
return parent;
}
public void setParent(String parent) {
this.parent = parent;
}
public String getNodeName() {
return nodeName;
}
public void setNodeName(String nodeName) {
this.nodeName = nodeName;
}
public String getNodeHref() {
return nodeHref;
}
public void setNodeHref(String nodeHref) {
this.nodeHref = nodeHref;
}
#Override
public String toString() {
return "ProjectNode [parent=" + parent + ", nodeName=" + nodeName + ", nodeHref=" + nodeHref + ", hasChild="
+ hasChild + ", td=" + td + ", children=" +"]";
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((children == null) ? 0 : children.hashCode());
result = prime * result + (hasChild ? 1231 : 1237);
result = prime * result + ((nodeHref == null) ? 0 : nodeHref.hashCode());
result = prime * result + ((nodeName == null) ? 0 : nodeName.hashCode());
result = prime * result + ((parent == null) ? 0 : parent.hashCode());
result = prime * result + td;
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ProjectNode other = (ProjectNode) obj;
if (children == null) {
if (other.children != null)
return false;
} else if (!children.equals(other.children))
return false;
if (hasChild != other.hasChild)
return false;
if (nodeHref == null) {
if (other.nodeHref != null)
return false;
} else if (!nodeHref.equals(other.nodeHref))
return false;
if (nodeName == null) {
if (other.nodeName != null)
return false;
} else if (!nodeName.equals(other.nodeName))
return false;
if (parent == null) {
if (other.parent != null)
return false;
} else if (!parent.equals(other.parent))
return false;
if (td != other.td)
return false;
return true;
}
#Override
public int compareTo(ProjectNode o) {
// TODO Auto-generated method stub
return nodeName.compareTo(o.getNodeName());
}
}
I would use recursive to groupd all nodes in corect place but i had same error (with stackoverflow) so i had to use work around which is addToParent() function.
I have managed it by breaking loop when parent of my node have been found. I made it just for performance because before even if parent has been found loop was checking all elements anyway so i added break, and it works.. Not sure why..
Code below:
public void group() {
int td = this.highestTd;
while (td > 2) {
List<ProjectNode> toRemove = new ArrayList<ProjectNode>();
for (ProjectNode pnA : this.NodeList) {
if(pnA.getTd()==3) {
pnA.setParent("root");
}
if (pnA.getTd() == td) {
for (ProjectNode pnB : this.NodeList) {
System.out.println(pnB.toString());
if (pnA.getParent()!=null && pnA.getParent().equals(pnB.getNodeName())) {
System.out.println("Dodaje "+pnA.getNodeName() + " Do "+pnB.getNodeName());
pnB.addChlild(pnA);
toRemove.add(pnA);
break;
}
}
}
}
td--;
this.NodeList.removeAll(toRemove);
}
}
How do I use DOTGenerator to convert a parse tree to DOT/graphviz format in ANTLR4?
I found this related question but the only answer uses TreeViewer to display the tree in a JPanel and that's not what I'm after. This other question is exacly what I need but it didn't get answered. Everything else I stumbled upon relates to DOTTreeGenerator from ANTLR3 and it's not helpful.
I'm using Java with the ANTLR4 plugin for IntelliJ.
I have a small project that has all kind of utility methods w.r.t. ANTLR4 grammar debugging/testing. I haven't found the time to provide it of some proper documentation so that I can put it on Github. But here's a part of it responsible for creating a DOT file from a grammar.
Stick it all in a single file called Main.java (and of course generate the lexer and parser for Expression.g4), and you will see a DOT string being printed to your console:
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.tree.ParseTree;
import java.util.*;
public class Main {
public static void main(String[] args) {
/*
// Expression.g4
grammar Expression;
expression
: '-' expression
| expression ('*' | '/') expression
| expression ('+' | '-') expression
| '(' expression ')'
| NUMBER
| VARIABLE
;
NUMBER
: [0-9]+ ( '.' [0-9]+ )?
;
VARIABLE
: [a-zA-Z] [a-zA-Z0-9]+
;
SPACE
: [ \t\r\n] -> skip
;
*/
String source = "3 + 42 * (PI - 3.14159)";
ExpressionLexer lexer = new ExpressionLexer(CharStreams.fromString(source));
ExpressionParser parser = new ExpressionParser(new CommonTokenStream(lexer));
SimpleTree tree = new SimpleTree.Builder()
.withParser(parser)
.withParseTree(parser.expression())
.withDisplaySymbolicName(false)
.build();
DotOptions options = new DotOptions.Builder()
.withParameters(" labelloc=\"t\";\n label=\"Expression Tree\";\n\n")
.withLexerRuleShape("circle")
.build();
System.out.println(new DotTreeRepresentation().display(tree, options));
}
}
class DotTreeRepresentation {
public String display(SimpleTree tree) {
return display(tree, DotOptions.DEFAULT);
}
public String display(SimpleTree tree, DotOptions options) {
return display(new InOrderTraversal().traverse(tree), options);
}
public String display(List<SimpleTree.Node> nodes, DotOptions options) {
StringBuilder builder = new StringBuilder("graph tree {\n\n");
Map<SimpleTree.Node, String> nodeNameMap = new HashMap<>();
int nodeCount = 0;
if (options.parameters != null) {
builder.append(options.parameters);
}
for (SimpleTree.Node node : nodes) {
nodeCount++;
String nodeName = String.format("node_%s", nodeCount);
nodeNameMap.put(node, nodeName);
builder.append(String.format(" %s [label=\"%s\", shape=%s];\n",
nodeName,
node.getLabel().replace("\"", "\\\""),
node.isTokenNode() ? options.lexerRuleShape : options.parserRuleShape));
}
builder.append("\n");
for (SimpleTree.Node node : nodes) {
String name = nodeNameMap.get(node);
for (SimpleTree.Node child : node.getChildren()) {
String childName = nodeNameMap.get(child);
builder.append(" ").append(name).append(" -- ").append(childName).append("\n");
}
}
return builder.append("}\n").toString();
}
}
class InOrderTraversal {
public List<SimpleTree.Node> traverse(SimpleTree tree) {
if (tree == null)
throw new IllegalArgumentException("tree == null");
List<SimpleTree.Node> nodes = new ArrayList<>();
traverse(tree.root, nodes);
return nodes;
}
private void traverse(SimpleTree.Node node, List<SimpleTree.Node> nodes) {
if (node.hasChildren()) {
traverse(node.getChildren().get(0), nodes);
}
nodes.add(node);
for (int i = 1; i < node.getChildCount(); i++) {
traverse(node.getChild(i), nodes);
}
}
}
class DotOptions {
public static final DotOptions DEFAULT = new DotOptions.Builder().build();
public static final String DEFAULT_PARAMETERS = null;
public static final String DEFAULT_LEXER_RULE_SHAPE = "box";
public static final String DEFAULT_PARSER_RULE_SHAPE = "ellipse";
public static class Builder {
private String parameters = DEFAULT_PARAMETERS;
private String lexerRuleShape = DEFAULT_LEXER_RULE_SHAPE;
private String parserRuleShape = DEFAULT_PARSER_RULE_SHAPE;
public DotOptions.Builder withParameters(String parameters) {
this.parameters = parameters;
return this;
}
public DotOptions.Builder withLexerRuleShape(String lexerRuleShape) {
this.lexerRuleShape = lexerRuleShape;
return this;
}
public DotOptions.Builder withParserRuleShape(String parserRuleShape) {
this.parserRuleShape = parserRuleShape;
return this;
}
public DotOptions build() {
if (lexerRuleShape == null)
throw new IllegalStateException("lexerRuleShape == null");
if (parserRuleShape == null)
throw new IllegalStateException("parserRuleShape == null");
return new DotOptions(parameters, lexerRuleShape, parserRuleShape);
}
}
public final String parameters;
public final String lexerRuleShape;
public final String parserRuleShape;
private DotOptions(String parameters, String lexerRuleShape, String parserRuleShape) {
this.parameters = parameters;
this.lexerRuleShape = lexerRuleShape;
this.parserRuleShape = parserRuleShape;
}
}
class SimpleTree {
public static class Builder {
private Parser parser = null;
private ParseTree parseTree = null;
private Set<Integer> ignoredTokenTypes = new HashSet<>();
private boolean displaySymbolicName = true;
public SimpleTree build() {
if (parser == null) {
throw new IllegalStateException("parser == null");
}
if (parseTree == null) {
throw new IllegalStateException("parseTree == null");
}
return new SimpleTree(parser, parseTree, ignoredTokenTypes, displaySymbolicName);
}
public SimpleTree.Builder withParser(Parser parser) {
this.parser = parser;
return this;
}
public SimpleTree.Builder withParseTree(ParseTree parseTree) {
this.parseTree = parseTree;
return this;
}
public SimpleTree.Builder withIgnoredTokenTypes(Integer... ignoredTokenTypes) {
this.ignoredTokenTypes = new HashSet<>(Arrays.asList(ignoredTokenTypes));
return this;
}
public SimpleTree.Builder withDisplaySymbolicName(boolean displaySymbolicName) {
this.displaySymbolicName = displaySymbolicName;
return this;
}
}
public final SimpleTree.Node root;
private SimpleTree(Parser parser, ParseTree parseTree, Set<Integer> ignoredTokenTypes, boolean displaySymbolicName) {
this.root = new SimpleTree.Node(parser, parseTree, ignoredTokenTypes, displaySymbolicName);
}
public SimpleTree(SimpleTree.Node root) {
if (root == null)
throw new IllegalArgumentException("root == null");
this.root = root;
}
public SimpleTree copy() {
return new SimpleTree(root.copy());
}
public String toLispTree() {
StringBuilder builder = new StringBuilder();
toLispTree(this.root, builder);
return builder.toString().trim();
}
private void toLispTree(SimpleTree.Node node, StringBuilder builder) {
if (node.isLeaf()) {
builder.append(node.getLabel()).append(" ");
}
else {
builder.append("(").append(node.label).append(" ");
for (SimpleTree.Node child : node.children) {
toLispTree(child, builder);
}
builder.append(") ");
}
}
#Override
public String toString() {
return String.format("%s", this.root);
}
public static class Node {
protected String label;
protected int level;
protected boolean isTokenNode;
protected List<SimpleTree.Node> children;
Node(Parser parser, ParseTree parseTree, Set<Integer> ignoredTokenTypes, boolean displaySymbolicName) {
this(parser.getRuleNames()[((RuleContext)parseTree).getRuleIndex()], 0, false);
traverse(parseTree, this, parser, ignoredTokenTypes, displaySymbolicName);
}
public Node(String label, int level, boolean isTokenNode) {
this.label = label;
this.level = level;
this.isTokenNode = isTokenNode;
this.children = new ArrayList<>();
}
public void replaceWith(SimpleTree.Node node) {
this.label = node.label;
this.level = node.level;
this.isTokenNode = node.isTokenNode;
this.children.remove(node);
this.children.addAll(node.children);
}
public SimpleTree.Node copy() {
SimpleTree.Node copy = new SimpleTree.Node(this.label, this.level, this.isTokenNode);
for (SimpleTree.Node child : this.children) {
copy.children.add(child.copy());
}
return copy;
}
public void normalizeLevels(int level) {
this.level = level;
for (SimpleTree.Node child : children) {
child.normalizeLevels(level + 1);
}
}
public boolean hasChildren() {
return !children.isEmpty();
}
public boolean isLeaf() {
return !hasChildren();
}
public int getChildCount() {
return children.size();
}
public SimpleTree.Node getChild(int index) {
return children.get(index);
}
public int getLevel() {
return level;
}
public String getLabel() {
return label;
}
public boolean isTokenNode() {
return isTokenNode;
}
public List<SimpleTree.Node> getChildren() {
return new ArrayList<>(children);
}
private void traverse(ParseTree parseTree, SimpleTree.Node parent, Parser parser, Set<Integer> ignoredTokenTypes, boolean displaySymbolicName) {
List<SimpleTree.ParseTreeParent> todo = new ArrayList<>();
for (int i = 0; i < parseTree.getChildCount(); i++) {
ParseTree child = parseTree.getChild(i);
if (child.getPayload() instanceof CommonToken) {
CommonToken token = (CommonToken) child.getPayload();
if (!ignoredTokenTypes.contains(token.getType())) {
String tempText = displaySymbolicName ?
String.format("%s: '%s'",
parser.getVocabulary().getSymbolicName(token.getType()),
token.getText()
.replace("\r", "\\r")
.replace("\n", "\\n")
.replace("\t", "\\t")
.replace("'", "\\'")) :
String.format("%s",
token.getText()
.replace("\r", "\\r")
.replace("\n", "\\n")
.replace("\t", "\\t"));
if (parent.label == null) {
parent.label = tempText;
}
else {
parent.children.add(new SimpleTree.Node(tempText, parent.level + 1, true));
}
}
}
else {
SimpleTree.Node node = new SimpleTree.Node(parser.getRuleNames()[((RuleContext)child).getRuleIndex()], parent.level + 1, false);
parent.children.add(node);
todo.add(new SimpleTree.ParseTreeParent(child, node));
}
}
for (SimpleTree.ParseTreeParent wrapper : todo) {
traverse(wrapper.parseTree, wrapper.parent, parser, ignoredTokenTypes, displaySymbolicName);
}
}
#Override
public String toString() {
return String.format("{label=%s, level=%s, isTokenNode=%s, children=%s}", label, level, isTokenNode, children);
}
}
private static class ParseTreeParent {
final ParseTree parseTree;
final SimpleTree.Node parent;
private ParseTreeParent(ParseTree parseTree, SimpleTree.Node parent) {
this.parseTree = parseTree;
this.parent = parent;
}
}
}
And if you paste the output in a DOT viewer, you will get this:
You may also want to look at alternatives. DOT graphs aren't the pretties among possible graph representations. Maybe you like an svg graph instead? If so have a look at the ANTLR4 grammar extension for Visual Studio Code, which generates and exports an svg graphic with the click of a mouse button (and you can style that with own CSS code).
I am trying to remove duplicate Set of custom objects from ArrayList. Below is the code I have written which uses toString representation of custom EmployeeObj to compare. Can you please suggest what other approaches can be taken?
package com.collections;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class DupSetInsideList {
public static void main(String[] args) {
List<Set<EmployeeObj>> list = new ArrayList<Set<EmployeeObj>>();
Set<EmployeeObj> set1 = new HashSet<EmployeeObj>();
Set<EmployeeObj> set2 = new HashSet<EmployeeObj>();
Set<EmployeeObj> set3 = new HashSet<EmployeeObj>();
list.add(set1);
list.add(set2);
list.add(set3);
EmployeeObj empObj1 = new EmployeeObj(1, "Nikhil");
EmployeeObj empObj2 = new EmployeeObj(2, "Rakesh");
EmployeeObj empObj3 = new EmployeeObj(3, "Kunal");
set1.add(empObj1);
set1.add(empObj2);
set2.add(empObj1);
set2.add(empObj2);
set3.add(empObj1);
set3.add(empObj2);
set3.add(empObj3);
System.out.println("List with duplicaes: " + list);
//Output: List with duplicaes: [[1=Nikhil, 2=Rakesh], [1=Nikhil, 2=Rakesh], [3=Kunal, 1=Nikhil, 2=Rakesh]]
//Remove duplicates
List<Set<EmployeeObj>> nonDupList = new ArrayList<Set<EmployeeObj>>();
for(Set<EmployeeObj> obj1:list) {
if(!nonDupList.contains(obj1)) {
nonDupList.add(obj1);
}
}
System.out.println("List without duplicates: " + nonDupList);
//List without duplicates: [[1=Nikhil, 2=Rakesh], [3=Kunal, 1=Nikhil, 2=Rakesh]]
}
}
class EmployeeObj {
private int id;
private String name;
public int getId() {
return id;
}
public String getName() {
return name;
}
public EmployeeObj(int id, String name) {
this.id = id;
this.name = name;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + id;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
EmployeeObj other = (EmployeeObj) obj;
if (id != other.id)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
#Override
public String toString() {
return id + "=" + name;
}
}
If you want a list behaviour guaranteeing a uniqueness of elements use a LinkedHashSet instead of ArrayList.
If you are bound to using ArrayList (as in a student exercise), extend it, overwrite add and addAll methods by checking the uniqueness first and then calling super.add resp. super.addAll and then use the new class in place of ArrayList.
The Set interface specifies the equals method as follows:
Compares the specified object with this set for equality. Returns true if the specified object is also a set, the two sets have the same size, and every member of the specified set is contained in this set (or equivalently, every member of this set is contained in the specified set).
So in order to create a list that contains no duplicates (even if the elements in the list are sets), one can simply write
//Remove duplicates
List<Set<EmployeeObj>> nonDupList =
new ArrayList<Set<EmployeeObj>>(
new LinkedHashSet<Set<EmployeeObj>>(list));
Try this solution:
private boolean equals(Set elements, Set elements2) {
return elements != null && elements.equals(elements2);
}
private List<Set> removeDuplicates(List<Set> from) {
List<Set> noDuplicates = new ArrayList<Set>();
for (Set possibleDuplicate : from) {
boolean alreadyInNoDuplicatesList = false;
for (Set elementFromNoDuplicateList : noDuplicates) {
if (equals(elementFromNoDuplicateList, possibleDuplicate)) {
alreadyInNoDuplicatesList = true;
break;
}
}
if (!alreadyInNoDuplicatesList) {
noDuplicates.add(possibleDuplicate);
}
}
return noDuplicates;
}
Put the Sets in a Set and they'll be removed as if by magic!
I have an ArrayList filled POJOs and I want to remove all POJOs, which have a duplicate variable. This is the POJO:
public static class UrlStore {
public String url;
public String data;
public UrlStore(String url) {
this.url = url;
}
public void setData(String data) {
this.data = data;
}
}
My way to remove duplicate "url"-variables in the ArrayList<UrlStore> is to iterate through the list and to remove those duplicates. It was said to me that I could simply use a Set to do this, but I can't figure out how to use it with an ArrayList containing POJOs. Or do you have even a better way?
Thanks for any suggestions!
You can override the equals() and hashCode() methods in your POJO and pass the List<UrlStore> to the Set.
List<UrlStore> listOfUrlStore = ......
Set<UrlStore> foo = new HashSet<UrlStore>(listOfUrlStore);
I have used a simple HashSet here , the correct implementation of Set depends on your requirement. You can even convert the Set back to the List .
listOfUrlStore.clear();
listOfUrlStore.addAll(foo);
package test.urlstore;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
public class DuplicateDemo{
public static void main(String[] args) throws Exception {
List<UrlStore> urlStores = new ArrayList<UrlStore>();
UrlStore usg = new UrlStore("google");
UrlStore usy = new UrlStore("yahoo");
UrlStore usb = new UrlStore("bing");
UrlStore usa = new UrlStore("ask");
UrlStore usd = new UrlStore("duckduckgo");
usg.setData("mail");
urlStores.add(usg);
usg = new UrlStore("google");
usg.setData("search");
urlStores.add(usg);
usg = new UrlStore("google");
usg.setData("doc");
urlStores.add(usg);
usg = new UrlStore("google");
usg.setData("search");
urlStores.add(usg);
usg = new UrlStore("google");
usy.setData("search");
urlStores.add(usy);
usy.setData("search");
urlStores.add(usy);
usb.setData("search");
urlStores.add(usb);
usb.setData("search");
urlStores.add(usb);
usa.setData("search");
urlStores.add(usa);
usd.setData("search");
urlStores.add(usd);
System.out.println("before removing duplicates");
// before removing duplicates
for (Iterator iterator = urlStores.iterator(); iterator.hasNext();) {
UrlStore urlStore = (UrlStore) iterator.next();
System.out.println(urlStore.toString());
}
System.out.println("\n\nafter removing duplicates");
//removing duplicates
Set<UrlStore> uniqueUrlStores = new HashSet<UrlStore>(urlStores);
//After removing duplicates
for (Iterator iterator = uniqueUrlStores.iterator(); iterator.hasNext();) {
UrlStore urlStore = (UrlStore) iterator.next();
System.out.println(urlStore.toString());
}
}
static class UrlStore {
public String url;
public String data;
public UrlStore(String url) {
this.url = url;
}
public void setData(String data) {
this.data = data;
}
#Override
public String toString() {
return "UrlStore [url=" + url + ", data=" + data + "]";
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((data == null) ? 0 : data.hashCode());
result = prime * result + ((url == null) ? 0 : url.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
UrlStore other = (UrlStore) obj;
if (data == null) {
if (other.data != null)
return false;
} else if (!data.equals(other.data))
return false;
if (url == null) {
if (other.url != null)
return false;
} else if (!url.equals(other.url))
return false;
return true;
}
}
}
Override hashCode() and equals() in your POJO and then:
List<URLStore>() list = //Your list;
Set<URLStore> set =new HashSet<URLStore>(list);
Don't forget to override the equals method of your POJO.
One this is done, you could use contains method of List to check if your object is in the list before add it.
For the Set, you don't have to use it with the list, it replace the list. You can populate a Set from a List with addAll(Collection c)
I have an array list that contains Quote objects. I want to be able to sort alphabetically by name, by change, and by percent change. How can I sort my arraylist?
package org.stocktwits.model;
import java.io.Serializable;
import java.text.DecimalFormat;
public class Quote implements Serializable {
private static final long serialVersionUID = 1L;
public String symbol;
public String name;
public String change;
public String percentChange;
public String open;
public String daysHigh;
public String daysLow;
public String dividendYield;
public String volume;
public String averageDailyVolume;
public String peRatio;
public String marketCapitalization;
public String yearHigh;
public String yearLow;
public String lastTradePriceOnly;
public DecimalFormat df = new DecimalFormat("#,###,###,###,###,##0.00");
public DecimalFormat vf = new DecimalFormat("#,###,###,###,###,##0");
public String getSymbol() {
return symbol;
}
public void setSymbol(String symbol) {
this.symbol = symbol;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getChange() {
return change;
}
public void setChange(String change) {
if(change.equals("null")){
this.change = "N/A";
}
else{
float floatedChange = Float.valueOf(change);
this.change = (df.format(floatedChange));
}
}
public String getPercentChange() {
return percentChange;
}
public void setPercentChange(String percentChange) {
if(percentChange.equals("null"))
percentChange = "N/A";
else
this.percentChange = percentChange;
}
public String getOpen() {
return open;
}
public void setOpen(String open) {
if(open.equals("null"))
this.open = "N/A";
else
this.open = open;
}
public String getDaysHigh() {
return daysHigh;
}
public void setDaysHigh(String daysHigh) {
if(daysHigh.equals("null"))
this.daysHigh = "N/A";
else{
float floatedDaysHigh = Float.valueOf(daysHigh);
this.daysHigh = (df.format(floatedDaysHigh));
}
}
public String getDaysLow() {
return daysLow;
}
public void setDaysLow(String daysLow) {
if(daysLow.equals("null"))
this.daysLow = "N/A";
else{
float floatedDaysLow = Float.valueOf(daysLow);
this.daysLow = (df.format(floatedDaysLow));
}
}
public String getVolume() {
return volume;
}
public void setVolume(String volume) {
if(volume.equals("null")){
this.volume = "N/A";
}
else{
float floatedVolume = Float.valueOf(volume);
this.volume = (vf.format(floatedVolume));
}
}
public String getDividendYield() {
return dividendYield;
}
public void setDividendYield(String dividendYield) {
if(dividendYield.equals("null"))
this.dividendYield = "N/A";
else
this.dividendYield = dividendYield;
}
public String getAverageDailyVolume() {
return averageDailyVolume;
}
public void setAverageDailyVolume(String averageDailyVolume) {
if(averageDailyVolume.equals("null")){
this.averageDailyVolume = "N/A";
}
else{
float floatedAverageDailyVolume = Float.valueOf(averageDailyVolume);
this.averageDailyVolume = (vf.format(floatedAverageDailyVolume));
}
}
public String getPeRatio() {
return peRatio;
}
public void setPeRatio(String peRatio) {
if(peRatio.equals("null"))
this.peRatio = "N/A";
else
this.peRatio = peRatio;
}
public String getMarketCapitalization() {
return marketCapitalization;
}
public void setMarketCapitalization(String marketCapitalization) {
if(marketCapitalization.equals("null"))
this.marketCapitalization = "N/A";
else
this.marketCapitalization = marketCapitalization;
}
public String getYearHigh() {
return yearHigh;
}
public void setYearHigh(String yearHigh) {
if(yearHigh.equals("null"))
this.yearHigh = "N/A";
else
this.yearHigh = yearHigh;
}
public String getYearLow() {
return yearLow;
}
public void setYearLow(String yearLow) {
if(yearLow.equals("null"))
this.yearLow = "N/A";
else
this.yearLow = yearLow;
}
public String getLastTradePriceOnly() {
return lastTradePriceOnly;
}
public void setLastTradePriceOnly(String lastTradePriceOnly) {
if(lastTradePriceOnly.equals("null")){
this.lastTradePriceOnly = "N/A";
}
else{
float floatedLastTradePriceOnly = Float.valueOf(lastTradePriceOnly);
this.lastTradePriceOnly = (df.format(floatedLastTradePriceOnly));
}
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((change == null) ? 0 : change.hashCode());
result = prime * result
+ ((daysHigh == null) ? 0 : daysHigh.hashCode());
result = prime * result + ((daysLow == null) ? 0 : daysLow.hashCode());
result = prime
* result
+ ((lastTradePriceOnly == null) ? 0 : lastTradePriceOnly
.hashCode());
result = prime
* result
+ ((marketCapitalization == null) ? 0 : marketCapitalization
.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((open == null) ? 0 : open.hashCode());
result = prime * result + ((peRatio == null) ? 0 : peRatio.hashCode());
result = prime * result
+ ((percentChange == null) ? 0 : percentChange.hashCode());
result = prime * result + ((symbol == null) ? 0 : symbol.hashCode());
result = prime * result + ((volume == null) ? 0 : volume.hashCode());
result = prime * result
+ ((yearHigh == null) ? 0 : yearHigh.hashCode());
result = prime * result + ((yearLow == null) ? 0 : yearLow.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Quote other = (Quote) obj;
if (change == null) {
if (other.change != null)
return false;
} else if (!change.equals(other.change))
return false;
if (daysHigh == null) {
if (other.daysHigh != null)
return false;
} else if (!daysHigh.equals(other.daysHigh))
return false;
if (daysLow == null) {
if (other.daysLow != null)
return false;
} else if (!daysLow.equals(other.daysLow))
return false;
if (lastTradePriceOnly == null) {
if (other.lastTradePriceOnly != null)
return false;
} else if (!lastTradePriceOnly.equals(other.lastTradePriceOnly))
return false;
if (marketCapitalization == null) {
if (other.marketCapitalization != null)
return false;
} else if (!marketCapitalization.equals(other.marketCapitalization))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (open == null) {
if (other.open != null)
return false;
} else if (!open.equals(other.open))
return false;
if (peRatio == null) {
if (other.peRatio != null)
return false;
} else if (!peRatio.equals(other.peRatio))
return false;
if (percentChange == null) {
if (other.percentChange != null)
return false;
} else if (!percentChange.equals(other.percentChange))
return false;
if (symbol == null) {
if (other.symbol != null)
return false;
} else if (!symbol.equals(other.symbol))
return false;
if (volume == null) {
if (other.volume != null)
return false;
} else if (!volume.equals(other.volume))
return false;
if (yearHigh == null) {
if (other.yearHigh != null)
return false;
} else if (!yearHigh.equals(other.yearHigh))
return false;
if (yearLow == null) {
if (other.yearLow != null)
return false;
} else if (!yearLow.equals(other.yearLow))
return false;
return true;
}
}
If you (almost) always want to use that order you can add the Comparable interface to Quote and implement a compareTo method.
public int compareTo(Quote quote) {
int result = this.getName().compareTo(quote.getName());
if (result == 0) {
result = this.getChange().compareTo(quote.getChange());
}
if (result == 0) {
result = this.getPercentChange().compareTo(quote.getPercentChange());
}
return result;
}
Then use a sorted collection, or sort a list, and the quotes will be sorted.
For ad hoc sorting, a separate, possibly anonymous, Comparator is better.
Everybody is right that you want to use Comparators. Extending on that idea, if you want to be able to sort on multiple criteria, then a class like this will work for you:
public class MultiComparator<T> implements Comparator<T> {
private List<Comparator<T>> comparators;
public MultiComparator(List<Comparator<T>> comparators) {
this.comparators = comparators;
}
public int compare(T o1, T o2) {
for (Comparator<T> comparator : comparators) {
int comparison = comparator.compare(o1, o2);
if (comparison != 0) return comparison;
}
return 0;
}
}
Then you just write really simple comparators for whichever fields you desire and you can combine them into more complex comparators more easily and with more reuse.
Have a look at the ComparatorChain from the Apache Commons Collection. This should do the job. Don't implement logic if is already available and tested.
At the following site I have a tutorial: Sorting Objects By Multiple Attributes"
Create an appropiate Comparator that will compare two items according to your desired criteria. Then use Collections.sort() on your ArrayList.
If at a later time you want to sort by different criteria, call Collections.sort() again with a different Comparator.
Sun has devoted big part of its tutorial to sorting in Java collections:
http://download.oracle.com/javase/tutorial/collections/interfaces/order.html
It discusses both Comparable and Comparator interfaces with examples.
See Collections.sort with an explicit Comparator (or the Collections.sort kind that requires the input to implement Comparable, if you prefer).
There are two things:
Sorting on multiple fields of an object
Multilevel sorting (Here sorting done on first field and then next sorting applied on grouping done on similar items in previous sort)
For #2: I found this below article very much close to what i desire
http://strangeoptics.blogspot.com/2011/09/sorting-objects-by-multiple-attributes.html