How can I represent a tree structure like below, in java?
"root"
| |
"leaf1" "leaf2"
| |
"leaf3" "leaf4"
|
"leaf5"
Are there any built-in or custom classes anyone can refer me to?
EDIT: I need to be able to easily traverse through nodes.
There is no generic tree type in the Java class libraries, or in either Guava or Apache Commons Collections.
The easiest solution is to implement the tree type yourself to do exactly what you require. The core functionality of a tree is trivial ... modulo that the details depend heavily on what the tree needs to contain and how your use-case requires it to behave.
(If you want to understand why there is no generic tree type, try to get your head around the discussion on this Guava issue - http://code.google.com/p/guava-libraries/issues/detail?id=174)
Following is simple binary tree, that would solve your purpose.
http://www.java2s.com/Code/Java/Collections-Data-Structure/BinaryTree.htm
Try this [very general though]:
public class Tree {
private Node root;
public Tree(String rootData) {
root = new Node();
root.data = rootData;
root.children = new ArrayList<Node>();
}
private class Node {
private String data;
private Node parent;
private List<Node> children;
}
}
It might not be part of the Collections API, but Swing's JTree TreeModel is certainly a generic tree implementation: https://docs.oracle.com/javase/7/docs/api/javax/swing/tree/TreeModel.html
Just make your own Node class:
Node {
T value;
Node left;
Node right;
}
For a more complex implementation see Java's N-ary tree DefaultMutableTreeNode
Related
As the title say, is there a way to find the children of children node when listen or visit a node in ANTLR.
For example: (use grammars-v4-java lexer and parse rule)
First, I take a java file to grammar tree.
grun Java compilationUnit -gui Example.java
// Example.java
public class Example {
String name = "test";
void call(){
String name1 = "test";
}
}
and the grammar tree is
Then I try to use java to extends the baseListerner to listen enterClassDeclaration node. So I can get the ClassDeclarationContext node. I want to find the ClassDeclarationContext node's children of children that the child type is LocalDeclarationContext.
In this example:
public class MyListener extends JavaParserBaseListener {
#Override
public void enterClassDeclaration(JavaParser.ClassDeclarationContext ctx) {
// find the children of children by ctx
List<ParserRuleContext> contexts = findChildContextBy(ctx, LocalVariableDeclarationContext.class);
super.enterClassDeclaration(ctx);
}
}
The variable contexts should has two elements. name and name1
I do not want to find the children one layer by one layer. emmm, Is there have a convenient way?
For a given parse tree it's easy to look up specific child nodes (at any nesting level) using ANTLR4's XPath implementation.
You can trigger that search from either the full parse tree return by the called parser rule or within a listener/visitor method for the particular subtree, for example:
List<ParseTreeMatch> matches = XPath.findAll(ctx, "//localVariableDeclaration", parser);
The return matches are instances of LocalVariableDeclarationContext (if any matched).
Note: the linked page describe two search utilities, parse tree matching and XPath, which can be used individually or together.
I understand the difference between (Prefix) Trie, a Suffix Trie and a Suffix Tree and I am trying to write Java code for both. What is the Java representation/structure of the SuffixTrieNode and SuffixTreeNode class?
SuffixTrie representation:
class SuffixTrie{
SuffixTrieNode root;
class SuffixTrieNode{
SuffixTrieNode[] links;
}
}
SuffixTree representation:
class SuffixTree{
SuffixTreeNode root;
class SuffixTreeNode{
SuffixTreeNode[] links;
}
}
Thanks!!
A suffix trie uses a trie data structure. It is the simplest way to build a suffix tree:Suffix tree and Tries. What is the difference?.
I have a XML file resulted from an input java file. I also have xPath expressions for the XML file.
I need a function that receives one xPath expression and return its java element (in the abstract syntax tree). I tried the below code:
First extract XML element based on the input xPath expression.
XPath xPath = XPathFactory.newInstance().newXPath();
String query = "//unit[1]/unit[1]/class[1]/block[1]/function[6]"; //a method
Node node = (Node) xPath.compile(query).evaluate(XmlDocument, XPathConstants.NODE);
However, I do not know how to link extracted XML node to Java element in the source code.
PS:
The reslut should be a node in the abstract syntax tree. I have AST created by spoon. Therefore, in the above example, I want to extract related CtMethodImpl.
node.getTextContent() is not the answer as it is possible that there is more than one instance with the similar text content.
To the best of my knowledge there is no 'direct' way of doing this.
This: "//unit[1]/unit[1]/class[1]/block[1]/function[6]" is what we call a signature in the sense that it uniquely identifies an element (somehow).
What I would do is to create a spoon processor and go through the entire AST checking each element to see if it matches the signature.
public class ProcessorExample <E extends CtElement> extends AbstractProcessor<E> {
HashMap<String, Node> nodes;
//Sets your XML Nodes here, sorted by signature
public void setNodes(HashMap<String, Node> nodes) {
this.nodes = nodes;
}
#Override
public void process(E element) {
if (nodes.containsKey(signature(element))) {
Node n = nodes.get(signature(element));
//YOU FOUND IT!
}
}
private String signature(E element) {
//YOU MUST PROVIDE THIS IMPLEMENTATION
//TO MATCH YOUR "//unit[1]/unit[1]/class[1]/block[1]/function[6]"
//KIND OF SIGNATURE
return null;
}
}
My graph contains nodes called points and lines.
There is a relationship type called "NEXT", which connects two points and has a property called lineID (a long). A line node consists simply of an ID and a reference to a "root" point. To traverse a line is to start with its root node and follow the NEXT relationships whose lineID matches the id of the line being traversed. To clarify, if we're traversing a line with ID 123, whose root point has id 321, the Cypher traversal would be:
START n = node(321)
MATCH (n)-[rel:NEXT*{lineID:123}]->(x)
RETURN collect(rel)
A line, then, is essentially a linked list of Next relationships with matching lineID properties. That said, I don't want to persist this list as a property of lines - I want the list to be constructed by a traversal when a line is loaded.
What are my options for implementing this in spring-data-neo4j? Specifically, should "lines" exist as NodeEntitys, and if so what should they contain?
#NodeEntity
class Line {
#RelatedTo(type="ROOT")
Point root;
#RelatedToVia(type="NEXT")
Iterable<Item> list;
doesn't quite fit, because the line is not related via Next relationships to the item, the root point is. It also fails to address the fact that those NEXT relationships need to have a lineID property matching the line's ID (which becomes important because some points exist on multiple lines - i.e. they have multiple NEXT relationships with different lineID's). I have a hunch that the solution will involve annotating the list as a #GraphTraversal, but I don't understand how that would work.
I'm doing this largely as an exercise to wrap my head around data modeling in SDN, in the context of wrapping my head around Neo4j and graph databases in general. If the question I'm asking reveals a flaw in my understanding of any of these things, I'd be very appreciative if someone could point it out.
This should be a suitable model for your entities:
#NodeEntity
class Point {
#GraphId
protected Long id;
#RelatedToVia(type="NEXT")
Set<Edge> edges;
}
#NodeEntity
class Line {
#GraphId
protected Long id;
#RelatedTo(type="ROOT")
Point root;
}
#RelationshipEntity
public class Edge {
#GraphId
protected Long id;
#StartNode private Point from;
#EndNode private Point to;
#RelatedTo(type="LINE")
Line line;
}
It easily allows both programmatic navigation in Java as in:
Set edges = line.getPoint().getEdges();
for (Edge edge: edges) {
if (edge.getLine().getId() == id) {
...
}
}
or Cypher queries like the one you listed.
Somewhat new to Java. I have used various Java collections (treeset, hashmap, arraylist) before quite successfully. My problem is similar to a Facebook-like network. I have various users in a membership organization and I want to store in a collection for each individual in our membership other members who are linked to this member by interest. I thought the simplest solution would be to dynamically allocate a new simple collection by name for each member that would have other member names (existing or new) linked, but it appears Java does not allow dynamic allocation of new collections.
I could have a concatenated string in a hashmap listing all the names associated with the key name, but this seems an akward solution. I assume this is a social common network-like problem that has an elegant solution. Suggestions?
Why don't you model it like a graph?
class Node {
private String name;
// TODO: Write your getters / setters.
}
class Edge {
private Edge source, destination;
// TODO: Write your getters / setters.
}
List<Node> nodes = new ArrayList<Node>();
List<Edge> edges = new ArrayList<Edge>();
Then, if you encounter a relationship you can do the following:
Node alice = new Node("Alice Kentucky");
if (!nodes.contains(alice)) { nodes.add(alice); }
edges.add(new Edge(bob, alice)); // where Bob is already in the node list